feat(fixtures): add npm fixture shims
This commit is contained in:
parent
ac38ebbd2a
commit
e130cf4623
48
.github/dependabot.yml
vendored
48
.github/dependabot.yml
vendored
@ -12,3 +12,51 @@ updates:
|
||||
commit-message:
|
||||
prefix: "chore"
|
||||
include: "scope"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/plugins/memory-tencentdb"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "09:10"
|
||||
timezone: "Etc/UTC"
|
||||
open-pull-requests-limit: 5
|
||||
commit-message:
|
||||
prefix: "chore"
|
||||
include: "scope"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/plugins/yuanbao"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "09:20"
|
||||
timezone: "Etc/UTC"
|
||||
open-pull-requests-limit: 5
|
||||
commit-message:
|
||||
prefix: "chore"
|
||||
include: "scope"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/plugins/openclaw-weixin"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "09:30"
|
||||
timezone: "Etc/UTC"
|
||||
open-pull-requests-limit: 5
|
||||
commit-message:
|
||||
prefix: "chore"
|
||||
include: "scope"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/plugins/lightclawbot"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "09:40"
|
||||
timezone: "Etc/UTC"
|
||||
open-pull-requests-limit: 5
|
||||
commit-message:
|
||||
prefix: "chore"
|
||||
include: "scope"
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -7,7 +7,4 @@ coverage/
|
||||
dist/
|
||||
tmp/
|
||||
.crabpot/
|
||||
plugins/lightclawbot/
|
||||
plugins/memory-tencentdb/
|
||||
plugins/openclaw-weixin/
|
||||
plugins/yuanbao/
|
||||
plugins/*/.crabpot-package/
|
||||
|
||||
@ -209,7 +209,6 @@
|
||||
"name": "TencentDB Agent Memory",
|
||||
"package": {
|
||||
"name": "@tencentdb-agent-memory/memory-tencentdb",
|
||||
"version": "0.2.3",
|
||||
"tag": "latest"
|
||||
},
|
||||
"path": "plugins/memory-tencentdb",
|
||||
@ -251,7 +250,6 @@
|
||||
"name": "Tencent Yuanbao Bot",
|
||||
"package": {
|
||||
"name": "openclaw-plugin-yuanbao",
|
||||
"version": "2.11.0",
|
||||
"tag": "latest"
|
||||
},
|
||||
"path": "plugins/yuanbao",
|
||||
@ -267,7 +265,6 @@
|
||||
"name": "OpenClaw Weixin",
|
||||
"package": {
|
||||
"name": "@tencent-weixin/openclaw-weixin",
|
||||
"version": "2.1.10",
|
||||
"tag": "latest"
|
||||
},
|
||||
"path": "plugins/openclaw-weixin",
|
||||
@ -283,7 +280,6 @@
|
||||
"name": "LightClawBot",
|
||||
"package": {
|
||||
"name": "lightclawbot",
|
||||
"version": "1.1.2",
|
||||
"tag": "latest"
|
||||
},
|
||||
"path": "plugins/lightclawbot",
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
"repo": { "type": "string", "pattern": "^https://github.com/.+\\.git$" },
|
||||
"package": {
|
||||
"type": "object",
|
||||
"required": ["name", "version"],
|
||||
"required": ["name"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": { "type": "string", "minLength": 1 },
|
||||
|
||||
@ -1,22 +1,25 @@
|
||||
# Crabpot Plugin Fixtures
|
||||
|
||||
Crabpot keeps external plugins under `plugins/`. Most fixtures are git
|
||||
submodules. Some npm-only fixtures are pinned by package version and unpacked on
|
||||
demand into ignored `plugins/<id>` directories. The parent repo owns only pins,
|
||||
fixture metadata, generated reports, and tests. Plugin source stays
|
||||
upstream-owned.
|
||||
submodules. Npm-only fixtures use committed `plugins/<id>/package.json` shim
|
||||
packages with one exact dependency pin; `node scripts/sync-fixtures.mjs --materialize`
|
||||
unpacks the package payload into ignored `plugins/<id>/.crabpot-package/`
|
||||
directories for static inspection. The parent repo owns only pins, fixture
|
||||
metadata, generated reports, and tests. Plugin source stays upstream-owned.
|
||||
|
||||
Dependabot watches `.gitmodules` with the `gitsubmodule` ecosystem and opens PRs
|
||||
when a submodule has a newer upstream commit. Npm-sourced fixtures are pinned in
|
||||
`crabpot.config.json` and are refreshed manually until we add package-update
|
||||
automation. Update PRs should change only the relevant pin unless plugin behavior
|
||||
requires reports or contract classifier changes.
|
||||
Dependabot watches `.gitmodules` with the `gitsubmodule` ecosystem and the npm
|
||||
shim package directories with the `npm` ecosystem. Update PRs should change only
|
||||
the relevant pin unless plugin behavior requires report or contract classifier
|
||||
changes. Dependabot PRs can be auto-merged after CI refreshes the generated
|
||||
reports and dashboard.
|
||||
|
||||
The root `.github/dependabot.yml` owns this:
|
||||
|
||||
```yaml
|
||||
package-ecosystem: "gitsubmodule"
|
||||
directory: "/"
|
||||
package-ecosystem: "npm"
|
||||
directory: "/plugins/<id>"
|
||||
```
|
||||
|
||||
## How It Works
|
||||
@ -25,8 +28,9 @@ directory: "/"
|
||||
- `crabpot.config.json` declares the fixture id, seam coverage, expected hooks,
|
||||
expected registrations, source pin, and why the plugin belongs in Crabpot.
|
||||
- The gitlink at `plugins/<id>` pins the exact upstream commit Crabpot tests.
|
||||
- Npm fixtures use `package.name` + `package.version`; `node scripts/sync-fixtures.mjs --materialize`
|
||||
unpacks them into ignored `plugins/<id>` directories.
|
||||
- Npm fixtures use `crabpot.config.json` for package identity and
|
||||
`plugins/<id>/package.json` for the exact dependency pin; materialization
|
||||
unpacks the package into ignored `plugins/<id>/.crabpot-package/`.
|
||||
- `scripts/inspect-fixtures.mjs` reads source statically and checks expected
|
||||
hooks, registrations, manifests, packages, and SDK imports.
|
||||
- `scripts/generate-report.mjs` compares observed plugin seams with the target
|
||||
@ -83,15 +87,23 @@ directory: "/"
|
||||
npm view <package> version
|
||||
```
|
||||
|
||||
5. Add a fixture entry to `crabpot.config.json` with:
|
||||
5. Create `plugins/<id>/package.json` with one exact dependency on the upstream
|
||||
npm package and generate its lockfile:
|
||||
|
||||
```sh
|
||||
npm install --package-lock-only --ignore-scripts --prefix plugins/<id>
|
||||
```
|
||||
|
||||
6. Add a fixture entry to `crabpot.config.json` with:
|
||||
- `id`, `name`, `path`, and optional `subdir`
|
||||
- exactly one of `repo` or `package: { name, version, tag }`
|
||||
- exactly one of `repo` or `package: { name, tag }`
|
||||
- `priority`
|
||||
- seam labels
|
||||
- expected hooks, registrations, or manifest contracts
|
||||
- a specific `why`
|
||||
6. Add the fixture to the inventory table above.
|
||||
7. Run:
|
||||
7. Add an npm update block to `.github/dependabot.yml` for the new shim path.
|
||||
8. Add the fixture to the inventory table above.
|
||||
9. Run:
|
||||
|
||||
```sh
|
||||
node scripts/sync-fixtures.mjs --materialize
|
||||
@ -124,12 +136,13 @@ directory: "/"
|
||||
rm -rf .git/modules/plugins/<id>
|
||||
```
|
||||
|
||||
5. For an npm fixture, remove the ignored local unpacked directory.
|
||||
5. For an npm fixture, remove `plugins/<id>/package.json`, `plugins/<id>/package-lock.json`,
|
||||
its Dependabot npm block, and the ignored local `.crabpot-package/` directory.
|
||||
6. Regenerate reports and run `npm run check`.
|
||||
|
||||
## Update A Pin Manually
|
||||
|
||||
Dependabot should handle routine updates. For a manual bump:
|
||||
Dependabot should handle routine updates. For a manual repo-backed bump:
|
||||
|
||||
```sh
|
||||
git submodule update --remote --depth 1 plugins/<id>
|
||||
@ -140,3 +153,7 @@ npm run check
|
||||
|
||||
Commit the gitlink bump with any necessary fixture/report changes. Do not edit
|
||||
upstream plugin source in this repository.
|
||||
|
||||
For an npm fixture, update the exact dependency in `plugins/<id>/package.json`,
|
||||
regenerate `plugins/<id>/package-lock.json`, then run the same report/check
|
||||
commands. Dependabot uses the same files.
|
||||
|
||||
6860
plugins/lightclawbot/package-lock.json
generated
Normal file
6860
plugins/lightclawbot/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
plugins/lightclawbot/package.json
Normal file
14
plugins/lightclawbot/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@crabpot/fixture-lightclawbot",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "Crabpot npm fixture shim for LightClawBot.",
|
||||
"dependencies": {
|
||||
"lightclawbot": "1.1.2"
|
||||
},
|
||||
"crabpot": {
|
||||
"fixture": "lightclawbot",
|
||||
"source": "npm",
|
||||
"package": "lightclawbot"
|
||||
}
|
||||
}
|
||||
488
plugins/memory-tencentdb/package-lock.json
generated
Normal file
488
plugins/memory-tencentdb/package-lock.json
generated
Normal file
@ -0,0 +1,488 @@
|
||||
{
|
||||
"name": "@crabpot/fixture-memory-tencentdb",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@crabpot/fixture-memory-tencentdb",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@tencentdb-agent-memory/memory-tencentdb": "0.2.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.1",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
||||
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
||||
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "0.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
|
||||
"integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.4.3",
|
||||
"@emnapi/runtime": "^1.4.3",
|
||||
"@tybys/wasm-util": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba/-/jieba-2.0.1.tgz",
|
||||
"integrity": "sha512-tnfzXOMqzVQF2dSKMhPC9HrHzzWmN6KheL/zYtGenhOpq/bCKHJWVASSggEnHlkmHgXGeIJHR2N/IuPzewz1BQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@node-rs/jieba-android-arm-eabi": "2.0.1",
|
||||
"@node-rs/jieba-android-arm64": "2.0.1",
|
||||
"@node-rs/jieba-darwin-arm64": "2.0.1",
|
||||
"@node-rs/jieba-darwin-x64": "2.0.1",
|
||||
"@node-rs/jieba-freebsd-x64": "2.0.1",
|
||||
"@node-rs/jieba-linux-arm-gnueabihf": "2.0.1",
|
||||
"@node-rs/jieba-linux-arm64-gnu": "2.0.1",
|
||||
"@node-rs/jieba-linux-arm64-musl": "2.0.1",
|
||||
"@node-rs/jieba-linux-x64-gnu": "2.0.1",
|
||||
"@node-rs/jieba-linux-x64-musl": "2.0.1",
|
||||
"@node-rs/jieba-wasm32-wasi": "2.0.1",
|
||||
"@node-rs/jieba-win32-arm64-msvc": "2.0.1",
|
||||
"@node-rs/jieba-win32-ia32-msvc": "2.0.1",
|
||||
"@node-rs/jieba-win32-x64-msvc": "2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-android-arm-eabi": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-android-arm-eabi/-/jieba-android-arm-eabi-2.0.1.tgz",
|
||||
"integrity": "sha512-tavsIaxybnlA9tRbJ+oc3NW3zhx0d5rNiCGdpIdGWjflwS7HyeUTVAZmAFDlg58Mc6EjTdVKZH+RolBbAJtgcQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-android-arm64": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-android-arm64/-/jieba-android-arm64-2.0.1.tgz",
|
||||
"integrity": "sha512-AwdyqKvVNuSDnDq3anUfq+nJ5J/kzXjkfbr/1WY6TfaAlTNuuGVskuQv72/wIx/jn7NoXfm/UPuJrWYG16NC6w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-darwin-arm64": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-darwin-arm64/-/jieba-darwin-arm64-2.0.1.tgz",
|
||||
"integrity": "sha512-10+nwGQ6KzXXJlIL/sELA6Fi6m7eJ7xJksBiKuw1kxKUgaJwtVfAG0iqRF+NRQv0Sdq7r3k5ew9K9y0+IYaEcA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-darwin-x64": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-darwin-x64/-/jieba-darwin-x64-2.0.1.tgz",
|
||||
"integrity": "sha512-IJ5RK0X/uPQa1XRmTvwKSieya+w1IJeiKLw0EekoBFJKybXQdvo8/uqM/8z2eVJ8vQxW9X6K2vkVGFvYQa9dYA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-freebsd-x64": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-freebsd-x64/-/jieba-freebsd-x64-2.0.1.tgz",
|
||||
"integrity": "sha512-yg7vyhqzP2weJu5DJ3q9q4pb0b4GWWRwcv54zK7MSSA6KNJ/uQv2a4R9/qmptLU/fZv14gWuJBEMFdL7y1Dv2w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-linux-arm-gnueabihf": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm-gnueabihf/-/jieba-linux-arm-gnueabihf-2.0.1.tgz",
|
||||
"integrity": "sha512-fxQYunS7w2tv8XV9GigkWJPzHnbcw6tjrUdDu5/qU0FdQVEzGuEYG85DjlNf8lZTDGSUKHBVyAQs7bBIvq8yqg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-linux-arm64-gnu": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm64-gnu/-/jieba-linux-arm64-gnu-2.0.1.tgz",
|
||||
"integrity": "sha512-VnLU630hQIyO/fwyxh2vqZi72mO+hXkVUC3jVLPfOAlppinmsGX9N81tpTPUK3840hbV8WLtbYTWN1XodI38eg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-linux-arm64-musl": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-arm64-musl/-/jieba-linux-arm64-musl-2.0.1.tgz",
|
||||
"integrity": "sha512-K4EDyNixSLVdTNYnHwD+7I/ytvzpo7tt+vdCLqwQViiek2PMpL/FFRvA39uU2tk99jXIxvkczdxARG20BRZppg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-linux-x64-gnu": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-x64-gnu/-/jieba-linux-x64-gnu-2.0.1.tgz",
|
||||
"integrity": "sha512-sq3J6L2ANTE25I9eVFq/nb57OtXcvUIeUD1CTKJxwgTKIVmcB2LyOZpWf20AjHRUfbMER9Klqg5dgyyO+Six+w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-linux-x64-musl": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-linux-x64-musl/-/jieba-linux-x64-musl-2.0.1.tgz",
|
||||
"integrity": "sha512-0zfP9Qy68yEXrhBFknfhF6WUJDPU/8eRuyIrkMGdMjfRpxhpSbr2fMfnsqhOQLvhuK4w3iDFvTy4t5d0s6JKMA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-wasm32-wasi": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-wasm32-wasi/-/jieba-wasm32-wasi-2.0.1.tgz",
|
||||
"integrity": "sha512-7I5rJya5rlQNJIhv8PvPzIVT1/gVc0vFzHmlfRGwCPGDJ3tHVxkSPW34dDx3OgDmbIeadNpmgIyC1RaS9djPJg==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^0.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-win32-arm64-msvc": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-arm64-msvc/-/jieba-win32-arm64-msvc-2.0.1.tgz",
|
||||
"integrity": "sha512-Aj/2EwYSaPgAbKnSl+vKM/2kOaZNMZWnShiZzbSNyzlLy3eIOyOYVLbYRDno4547KngRxer8uzROhIQIwXwkvw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-win32-ia32-msvc": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-ia32-msvc/-/jieba-win32-ia32-msvc-2.0.1.tgz",
|
||||
"integrity": "sha512-tpJt3uuBlGrcOInQLTYvcgamQgfadl5cwExLYU+CX9rXKpXLDO31dIujUDBgNWoiQq3tOiU1/AKbT7ZdNd4lBQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/jieba-win32-x64-msvc": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/jieba-win32-x64-msvc/-/jieba-win32-x64-msvc-2.0.1.tgz",
|
||||
"integrity": "sha512-LDOyo2/2CO8UnpSGLJdgqtH8mOnsABPhNxkfIky7UT9cyLEzOaU44nbA5YzPGpBI3qzMbWcwJYQsjBcgK2VqAg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tencentdb-agent-memory/memory-tencentdb": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@tencentdb-agent-memory/memory-tencentdb/-/memory-tencentdb-0.2.3.tgz",
|
||||
"integrity": "sha512-XQ9+H4k5zCN+jI8KfINhZ9ElNF53MtH4FTh2r7akr96tWdXYRMjk14RrW2h4/aNJuKUlmlgt5RkNxrJpLk40sg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@node-rs/jieba": "^2.0.1",
|
||||
"@tencentdb-agent-memory/tcvdb-text": "^0.1.1",
|
||||
"json5": "^2.2.3",
|
||||
"sqlite-vec": "0.1.7-alpha.2",
|
||||
"undici": "8.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"export-tencent-vdb": "bin/export-tencent-vdb.mjs",
|
||||
"migrate-sqlite-to-tcvdb": "bin/migrate-sqlite-to-tcvdb.mjs",
|
||||
"read-local-memory": "bin/read-local-memory.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.16.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"node-llama-cpp": "^3.16.2",
|
||||
"openclaw": ">=2026.3.7"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"node-llama-cpp": {
|
||||
"optional": true
|
||||
},
|
||||
"openclaw": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tencentdb-agent-memory/tcvdb-text": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@tencentdb-agent-memory/tcvdb-text/-/tcvdb-text-0.1.1.tgz",
|
||||
"integrity": "sha512-LoCiOFDL7tk0mu6+4X2MfKXyL/iVXsiVIAmbryKaA7DcGiT62h9I1wgoobnCHYU9vmghMjjReJ4gy3lIii+WvA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@node-rs/jieba": "^2.0.1",
|
||||
"murmurhash": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
|
||||
"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/murmurhash": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/murmurhash/-/murmurhash-2.0.1.tgz",
|
||||
"integrity": "sha512-5vQEh3y+DG/lMPM0mCGPDnyV8chYg/g7rl6v3Gd8WMF9S429ox3Xk8qrk174kWhG767KQMqqxLD1WnGd77hiew==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sqlite-vec": {
|
||||
"version": "0.1.7-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/sqlite-vec/-/sqlite-vec-0.1.7-alpha.2.tgz",
|
||||
"integrity": "sha512-rNgRCv+4V4Ed3yc33Qr+nNmjhtrMnnHzXfLVPeGb28Dx5mmDL3Ngw/Wk8vhCGjj76+oC6gnkmMG8y73BZWGBwQ==",
|
||||
"license": "MIT OR Apache",
|
||||
"optionalDependencies": {
|
||||
"sqlite-vec-darwin-arm64": "0.1.7-alpha.2",
|
||||
"sqlite-vec-darwin-x64": "0.1.7-alpha.2",
|
||||
"sqlite-vec-linux-arm64": "0.1.7-alpha.2",
|
||||
"sqlite-vec-linux-x64": "0.1.7-alpha.2",
|
||||
"sqlite-vec-windows-x64": "0.1.7-alpha.2"
|
||||
}
|
||||
},
|
||||
"node_modules/sqlite-vec-darwin-arm64": {
|
||||
"version": "0.1.7-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/sqlite-vec-darwin-arm64/-/sqlite-vec-darwin-arm64-0.1.7-alpha.2.tgz",
|
||||
"integrity": "sha512-raIATOqFYkeCHhb/t3r7W7Cf2lVYdf4J3ogJ6GFc8PQEgHCPEsi+bYnm2JT84MzLfTlSTIdxr4/NKv+zF7oLPw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT OR Apache",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite-vec-darwin-x64": {
|
||||
"version": "0.1.7-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/sqlite-vec-darwin-x64/-/sqlite-vec-darwin-x64-0.1.7-alpha.2.tgz",
|
||||
"integrity": "sha512-jeZEELsQjjRsVojsvU5iKxOvkaVuE+JYC8Y4Ma8U45aAERrDYmqZoHvgSG7cg1PXL3bMlumFTAmHynf1y4pOzA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT OR Apache",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite-vec-linux-arm64": {
|
||||
"version": "0.1.7-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/sqlite-vec-linux-arm64/-/sqlite-vec-linux-arm64-0.1.7-alpha.2.tgz",
|
||||
"integrity": "sha512-6Spj4Nfi7tG13jsUG+W7jnT0bCTWbyPImu2M8nWp20fNrd1SZ4g3CSlDAK8GBdavX7wRlbBHCZ+BDa++rbDewA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT OR Apache",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite-vec-linux-x64": {
|
||||
"version": "0.1.7-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/sqlite-vec-linux-x64/-/sqlite-vec-linux-x64-0.1.7-alpha.2.tgz",
|
||||
"integrity": "sha512-IcgrbHaDccTVhXDf8Orwdc2+hgDLAFORl6OBUhcvlmwswwBP1hqBTSEhovClG4NItwTOBNgpwOoQ7Qp3VDPWLg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT OR Apache",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/sqlite-vec-windows-x64": {
|
||||
"version": "0.1.7-alpha.2",
|
||||
"resolved": "https://registry.npmjs.org/sqlite-vec-windows-x64/-/sqlite-vec-windows-x64-0.1.7-alpha.2.tgz",
|
||||
"integrity": "sha512-TRP6hTjAcwvQ6xpCZvjP00pdlda8J38ArFy1lMYhtQWXiIBmWnhMaMbq4kaeCYwvTTddfidatRS+TJrwIKB/oQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT OR Apache",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-8.0.2.tgz",
|
||||
"integrity": "sha512-B9MeU5wuFhkFAuNeA19K2GDFcQXZxq33fL0nRy2Aq30wdufZbyyvxW3/ChaeipXVfy/wUweZyzovQGk39+9k2w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=22.19.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
plugins/memory-tencentdb/package.json
Normal file
14
plugins/memory-tencentdb/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@crabpot/fixture-memory-tencentdb",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "Crabpot npm fixture shim for TencentDB Agent Memory.",
|
||||
"dependencies": {
|
||||
"@tencentdb-agent-memory/memory-tencentdb": "0.2.3"
|
||||
},
|
||||
"crabpot": {
|
||||
"fixture": "memory-tencentdb",
|
||||
"source": "npm",
|
||||
"package": "@tencentdb-agent-memory/memory-tencentdb"
|
||||
}
|
||||
}
|
||||
45
plugins/openclaw-weixin/package-lock.json
generated
Normal file
45
plugins/openclaw-weixin/package-lock.json
generated
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@crabpot/fixture-openclaw-weixin",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@crabpot/fixture-openclaw-weixin",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@tencent-weixin/openclaw-weixin": "2.1.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tencent-weixin/openclaw-weixin": {
|
||||
"version": "2.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@tencent-weixin/openclaw-weixin/-/openclaw-weixin-2.1.10.tgz",
|
||||
"integrity": "sha512-cEG6Iw5g2qqlA+8/TcmV+E8aFUEX0ruxF0+a5LgVy5wv56/qP07KoapfRa7YTRPzhRW5UDaz6zsZQArt/4ZNnA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"qrcode-terminal": "0.12.0",
|
||||
"zod": "4.3.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode-terminal": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz",
|
||||
"integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==",
|
||||
"bin": {
|
||||
"qrcode-terminal": "bin/qrcode-terminal.js"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
|
||||
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
plugins/openclaw-weixin/package.json
Normal file
14
plugins/openclaw-weixin/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@crabpot/fixture-openclaw-weixin",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "Crabpot npm fixture shim for OpenClaw Weixin.",
|
||||
"dependencies": {
|
||||
"@tencent-weixin/openclaw-weixin": "2.1.10"
|
||||
},
|
||||
"crabpot": {
|
||||
"fixture": "openclaw-weixin",
|
||||
"source": "npm",
|
||||
"package": "@tencent-weixin/openclaw-weixin"
|
||||
}
|
||||
}
|
||||
7544
plugins/yuanbao/package-lock.json
generated
Normal file
7544
plugins/yuanbao/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
plugins/yuanbao/package.json
Normal file
14
plugins/yuanbao/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@crabpot/fixture-yuanbao",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "Crabpot npm fixture shim for Tencent Yuanbao Bot.",
|
||||
"dependencies": {
|
||||
"openclaw-plugin-yuanbao": "2.11.0"
|
||||
},
|
||||
"crabpot": {
|
||||
"fixture": "yuanbao",
|
||||
"source": "npm",
|
||||
"package": "openclaw-plugin-yuanbao"
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@ import { existsSync } from "node:fs";
|
||||
import { readdir, readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { readManifest, repoRoot } from "./manifest-lib.mjs";
|
||||
import { fixtureCheckoutPath, fixtureSourceRoot, readManifest, repoRoot } from "./manifest-lib.mjs";
|
||||
|
||||
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||
await main();
|
||||
@ -61,8 +61,8 @@ export async function inspectManifest() {
|
||||
}
|
||||
|
||||
export async function inspectFixture(fixture) {
|
||||
const checkoutPath = path.join(repoRoot, fixture.path);
|
||||
const sourceRoot = fixture.subdir ? path.join(checkoutPath, fixture.subdir) : checkoutPath;
|
||||
const checkoutPath = fixtureCheckoutPath(fixture);
|
||||
const sourceRoot = fixtureSourceRoot(fixture);
|
||||
|
||||
if (!existsSync(checkoutPath)) {
|
||||
return emptyInspection(fixture, "missing");
|
||||
|
||||
@ -3,6 +3,7 @@ import path from "node:path";
|
||||
|
||||
export const repoRoot = path.resolve(import.meta.dirname, "..");
|
||||
export const manifestPath = path.join(repoRoot, "crabpot.config.json");
|
||||
export const npmPackagePayloadDir = ".crabpot-package";
|
||||
|
||||
export async function readManifest() {
|
||||
const raw = await readFile(manifestPath, "utf8");
|
||||
@ -57,9 +58,6 @@ export function validateManifest(manifest) {
|
||||
if (!fixture.package.name || typeof fixture.package.name !== "string") {
|
||||
errors.push(`${fixture.id}: package.name must be set`);
|
||||
}
|
||||
if (!fixture.package.version || typeof fixture.package.version !== "string") {
|
||||
errors.push(`${fixture.id}: package.version must be set`);
|
||||
}
|
||||
}
|
||||
if (!["high", "medium", "low"].includes(fixture.priority)) {
|
||||
errors.push(`${fixture.id}: priority must be high, medium, or low`);
|
||||
@ -79,3 +77,18 @@ export function validateManifest(manifest) {
|
||||
throw new Error(errors.join("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
export function fixtureCheckoutPath(fixture) {
|
||||
return path.join(repoRoot, fixture.path);
|
||||
}
|
||||
|
||||
export function fixtureSourceRoot(fixture) {
|
||||
const checkoutPath = fixtureCheckoutPath(fixture);
|
||||
if (fixture.subdir) {
|
||||
return path.join(checkoutPath, fixture.subdir);
|
||||
}
|
||||
if (fixture.package) {
|
||||
return path.join(checkoutPath, npmPackagePayloadDir);
|
||||
}
|
||||
return checkoutPath;
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { existsSync, readFileSync } from "node:fs";
|
||||
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { inspectManifest } from "./inspect-fixtures.mjs";
|
||||
import { readManifest, repoRoot } from "./manifest-lib.mjs";
|
||||
import { fixtureCheckoutPath, fixtureSourceRoot, readManifest, repoRoot } from "./manifest-lib.mjs";
|
||||
|
||||
export const defaultReportDir = path.join(repoRoot, "reports");
|
||||
export const defaultMarkdownReportPath = path.join(defaultReportDir, "crabpot-report.md");
|
||||
@ -1401,8 +1401,8 @@ function classifyPackageContracts({ fixture, inspection, fixtureReport, warnings
|
||||
}
|
||||
|
||||
async function buildFixtureReport(fixture, inspection) {
|
||||
const checkoutPath = path.join(repoRoot, fixture.path);
|
||||
const sourceRoot = fixture.subdir ? path.join(checkoutPath, fixture.subdir) : checkoutPath;
|
||||
const checkoutPath = fixtureCheckoutPath(fixture);
|
||||
const sourceRoot = fixtureSourceRoot(fixture);
|
||||
|
||||
const pluginManifests = await readPluginManifests(checkoutPath, sourceRoot);
|
||||
const packageSummaries = await readPackageSummaries(checkoutPath, sourceRoot);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import { existsSync } from "node:fs";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { readManifest, repoRoot } from "./manifest-lib.mjs";
|
||||
import { fixtureCheckoutPath, fixtureSourceRoot, readManifest, repoRoot } from "./manifest-lib.mjs";
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const strict = args.includes("--strict");
|
||||
@ -22,8 +22,8 @@ const rows = [];
|
||||
const missing = [];
|
||||
|
||||
for (const fixture of manifest.fixtures) {
|
||||
const checkoutPath = path.join(repoRoot, fixture.path);
|
||||
const pluginRoot = fixture.subdir ? path.join(checkoutPath, fixture.subdir) : checkoutPath;
|
||||
const checkoutPath = fixtureCheckoutPath(fixture);
|
||||
const pluginRoot = fixtureSourceRoot(fixture);
|
||||
|
||||
if (!existsSync(checkoutPath)) {
|
||||
rows.push(row(fixture, "missing", "not materialized"));
|
||||
@ -88,4 +88,3 @@ async function readPackageName(filePath) {
|
||||
return "invalid package.json";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import { mkdir, mkdtemp, readFile, readdir, rm } from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import path from "node:path";
|
||||
import { readManifest, repoRoot } from "./manifest-lib.mjs";
|
||||
import { fixtureSourceRoot, readManifest, repoRoot } from "./manifest-lib.mjs";
|
||||
|
||||
const args = new Set(process.argv.slice(2));
|
||||
const materialize = args.has("--materialize");
|
||||
@ -14,6 +14,7 @@ const manifest = await readManifest();
|
||||
|
||||
if (check) {
|
||||
await checkGitmodules(manifest);
|
||||
await checkNpmFixtureShims(manifest);
|
||||
console.log(`crabpot: manifest ok (${manifest.fixtures.length} fixtures)`);
|
||||
process.exit(0);
|
||||
}
|
||||
@ -60,9 +61,25 @@ async function checkGitmodules(manifest) {
|
||||
}
|
||||
}
|
||||
|
||||
async function checkNpmFixtureShims(manifest) {
|
||||
const errors = [];
|
||||
for (const fixture of manifest.fixtures.filter((item) => item.package)) {
|
||||
try {
|
||||
await readNpmFixtureDependency(fixture);
|
||||
} catch (error) {
|
||||
errors.push(error.message);
|
||||
}
|
||||
}
|
||||
if (errors.length > 0) {
|
||||
throw new Error(`npm fixture shims are invalid:\n${errors.join("\n")}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function materializeNpmFixture(fixture, target) {
|
||||
const spec = `${fixture.package.name}@${fixture.package.version}`;
|
||||
const dependency = await readNpmFixtureDependency(fixture);
|
||||
const spec = `${dependency.name}@${dependency.version}`;
|
||||
const tempDir = await mkdtemp(path.join(os.tmpdir(), "crabpot-npm-fixture-"));
|
||||
const payloadDir = fixtureSourceRoot(fixture);
|
||||
try {
|
||||
const pack = spawnSync("npm", ["pack", spec, "--pack-destination", tempDir, "--json"], {
|
||||
cwd: repoRoot,
|
||||
@ -80,14 +97,37 @@ async function materializeNpmFixture(fixture, target) {
|
||||
throw new Error(`npm pack ${spec} did not return a tarball filename`);
|
||||
}
|
||||
|
||||
await rm(target, { recursive: true, force: true });
|
||||
await mkdir(target, { recursive: true });
|
||||
run("tar", ["-xzf", path.join(tempDir, packed.filename), "-C", target, "--strip-components", "1"]);
|
||||
await rm(payloadDir, { recursive: true, force: true });
|
||||
await mkdir(payloadDir, { recursive: true });
|
||||
run("tar", ["-xzf", path.join(tempDir, packed.filename), "-C", payloadDir, "--strip-components", "1"]);
|
||||
} finally {
|
||||
await rm(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
async function readNpmFixtureDependency(fixture) {
|
||||
const shimPath = path.join(repoRoot, fixture.path, "package.json");
|
||||
if (!existsSync(shimPath)) {
|
||||
throw new Error(`${fixture.id}: missing npm shim ${path.relative(repoRoot, shimPath)}`);
|
||||
}
|
||||
const packageJson = JSON.parse(await readFile(shimPath, "utf8"));
|
||||
const declared =
|
||||
packageJson.dependencies?.[fixture.package.name] ??
|
||||
packageJson.devDependencies?.[fixture.package.name] ??
|
||||
packageJson.optionalDependencies?.[fixture.package.name];
|
||||
if (typeof declared !== "string") {
|
||||
throw new Error(`${fixture.id}: shim does not depend on ${fixture.package.name}`);
|
||||
}
|
||||
if (!/^\d+\.\d+\.\d+/.test(declared)) {
|
||||
throw new Error(`${fixture.id}: ${fixture.package.name} must use an exact semver pin, got ${declared}`);
|
||||
}
|
||||
return {
|
||||
name: fixture.package.name,
|
||||
version: declared,
|
||||
};
|
||||
}
|
||||
|
||||
async function hasEntries(target) {
|
||||
try {
|
||||
return (await readdir(target)).length > 0;
|
||||
|
||||
@ -54,7 +54,7 @@ test("manifest validation rejects invalid fixture contracts before CI materializ
|
||||
"duplicate fixture path: ../outside",
|
||||
"fixture must declare exactly one of repo or package",
|
||||
"repo must be a GitHub HTTPS .git URL",
|
||||
"package.version must be set",
|
||||
"package.name must be set",
|
||||
"priority must be high, medium, or low",
|
||||
"seams must be non-empty",
|
||||
"expect.hooks must be a non-empty array",
|
||||
@ -74,9 +74,7 @@ function invalidManifest() {
|
||||
id: "Bad_ID",
|
||||
path: "../outside",
|
||||
repo: "git@github.com:owner/repo",
|
||||
package: {
|
||||
name: "@scope/plugin",
|
||||
},
|
||||
package: {},
|
||||
priority: "urgent",
|
||||
seams: [],
|
||||
expect: {
|
||||
|
||||
@ -12,6 +12,18 @@ test("dependabot is configured to update plugin submodules", async () => {
|
||||
assert.match(dependabot, /interval:\s*"weekly"/);
|
||||
});
|
||||
|
||||
test("dependabot is configured to update npm fixture shims", async () => {
|
||||
const manifest = await readManifest();
|
||||
const dependabot = await readFile(".github/dependabot.yml", "utf8");
|
||||
|
||||
for (const fixture of manifest.fixtures.filter((item) => item.package)) {
|
||||
assert.match(
|
||||
dependabot,
|
||||
new RegExp(`package-ecosystem:\\s*"npm"[\\s\\S]*directory:\\s*"\\/${escapeRegExp(fixture.path)}"`),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("plugin submodule README stays aligned with manifest and gitmodules", async () => {
|
||||
const manifest = await readManifest();
|
||||
const gitmodules = await readFile(".gitmodules", "utf8");
|
||||
@ -23,6 +35,8 @@ test("plugin submodule README stays aligned with manifest and gitmodules", async
|
||||
assert.match(readme, /## Add A Plugin/);
|
||||
assert.match(readme, /## Remove A Plugin/);
|
||||
assert.match(readme, /package-ecosystem: "gitsubmodule"/);
|
||||
assert.match(readme, /package-ecosystem: "npm"/);
|
||||
assert.match(readme, /plugins\/<id>\/package\.json/);
|
||||
|
||||
for (const fixture of gitFixtures) {
|
||||
const submodule = submodules.find((item) => item.path === fixture.path);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user