Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
508f29d
fix(codex): add root-level marketplace.json so Codex CLI can recogniz…
May 25, 2026
796749a
chore: add .gitattributes (eol=lf) and sync package-lock.json to v3.7.4
May 25, 2026
59585ef
test(codex): sync codex-checks tests to new switchbot@switchbot defau…
May 25, 2026
9ec207b
chore: expand verify:pre-commit to include codex unit + integration t…
May 25, 2026
da2661c
fix(codex): fix marketplace registration — correct op order, clear st…
May 25, 2026
e7b8090
fix(codex): add root-level marketplace.json for git sparse checkout
May 25, 2026
6b844da
fix(codex): use .claude-plugin/marketplace.json — correct manifest lo…
May 25, 2026
c091b83
fix(codex): fix npm package structure for Route A and improve os-erro…
May 25, 2026
bf283da
build(codex): gate releases on plugin registration smokes
May 25, 2026
6c37ade
build(openclaw): restore npm publish path and align MCP entrypoint
May 25, 2026
9f8a24c
fix(codex): use CODEX_PLUGIN_DEFAULT_ID constant in repairStepRemoveP…
May 25, 2026
453b981
fix(codex): handle detached HEAD in smoke-codex-git-sparse
May 25, 2026
ac0f5c6
fix(smoke): make SHA detection case-insensitive and add error handlin…
May 25, 2026
063d294
fix(codex): read expected plugin version dynamically in smoke test
May 25, 2026
8a1d281
fix(codex-plugin): fix manifest fallback blocked by corrupt .claude-p…
May 25, 2026
329bb6d
fix(codex): verify registration sequence ordering in smoke test
May 25, 2026
5dbd891
test(codex): verify both --sparse flags in runCodexPluginRegistrationGit
May 25, 2026
8f09bd0
fix: add EPERM guard to resolveMarketplaceSourceRoot symlink creation
May 25, 2026
5cbb9c4
fix: add EPERM guard and test in bin/install.js resolveMarketplaceSou…
May 25, 2026
6bea63b
test: add EPERM coverage for dangling-symlink and stale-target branches
May 25, 2026
e5664c4
fix(ci): use lib/node_modules on Linux prefix install and fix Windows…
May 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "switchbot",
"plugins": [
{
"name": "switchbot",
"source": "./packages/codex-plugin/plugins/switchbot",
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
19 changes: 19 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Normalize line endings to LF in the repository.
# On checkout, Git will not convert to CRLF (eol=lf for text files).
# This eliminates phantom "modified" entries on Windows when core.autocrlf=true.

* text=auto eol=lf

# Explicitly binary — never touch line endings.
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.woff binary
*.woff2 binary
*.ttf binary
*.eot binary
*.zip binary
*.gz binary
*.tar binary
4 changes: 2 additions & 2 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ set -eu
REPO_ROOT="$(git rev-parse --show-toplevel)"
cd "$REPO_ROOT"

echo "[pre-push] tarball install smoke"
npm run verify:pre-push
echo "[pre-push] release gate"
npm run verify:release-gate
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,20 @@ jobs:
- run: npm run build
- name: npm pack -> npm install tarball -> switchbot --version / policy new / policy validate
run: npm run smoke:pack-install

codex-release-gates:
name: Codex release gates (${{ matrix.os }})
runs-on: ${{ matrix.os }}
needs: test
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20.x
cache: npm
- run: npm ci
- run: npm run verify:release-gate
3 changes: 3 additions & 0 deletions .github/workflows/npm-published-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
- package: '@switchbot/codex-plugin'
version_path: 'packages/codex-plugin/package.json'
kind: plugin
- package: '@switchbot/openclaw-skill'
version_path: 'packages/openclaw-skill/package.json'
kind: plugin
steps:
- uses: actions/checkout@v4
with:
Expand Down
47 changes: 36 additions & 11 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ jobs:
registry-url: https://registry.npmjs.org
cache: npm
- run: npm ci
- run: npm run build
- run: npm test
- run: npm run test:workspaces
- run: npm run verify:release-gate

- name: Verify tag matches root CLI package.json version
run: |
Expand All @@ -36,11 +34,14 @@ jobs:
run: |
CLI_VERSION=$(node -p "require('./package.json').version")
CODEX_VERSION=$(node -p "require('./packages/codex-plugin/package.json').version")
OPENCLAW_VERSION=$(node -p "require('./packages/openclaw-skill/package.json').version")
echo "Root CLI: @switchbot/openapi-cli@$CLI_VERSION"
echo "Codex plugin: @switchbot/codex-plugin@$CODEX_VERSION"
echo "OpenClaw plugin: @switchbot/openclaw-skill@$OPENCLAW_VERSION"
{
echo "cli_version=$CLI_VERSION"
echo "codex_version=$CODEX_VERSION"
echo "openclaw_version=$OPENCLAW_VERSION"
} >> "$GITHUB_OUTPUT"
id: versions

Expand All @@ -49,6 +50,7 @@ jobs:
env:
CLI_VERSION: ${{ steps.versions.outputs.cli_version }}
CODEX_VERSION: ${{ steps.versions.outputs.codex_version }}
OPENCLAW_VERSION: ${{ steps.versions.outputs.openclaw_version }}
run: |
# For each package, query npm; if the exact version is already published, skip.
check_unpublished() {
Expand All @@ -64,21 +66,16 @@ jobs:
}
CLI_PUBLISH=$(check_unpublished "@switchbot/openapi-cli" "$CLI_VERSION")
CODEX_PUBLISH=$(check_unpublished "@switchbot/codex-plugin" "$CODEX_VERSION")
OPENCLAW_PUBLISH=$(check_unpublished "@switchbot/openclaw-skill" "$OPENCLAW_VERSION")
echo "cli_publish=$CLI_PUBLISH"
echo "codex_publish=$CODEX_PUBLISH"
echo "openclaw_publish=$OPENCLAW_PUBLISH"
{
echo "cli_publish=$CLI_PUBLISH"
echo "codex_publish=$CODEX_PUBLISH"
echo "openclaw_publish=$OPENCLAW_PUBLISH"
} >> "$GITHUB_OUTPUT"

- name: Smoke test packed root CLI artifact
if: steps.detect.outputs.cli_publish == 'true'
run: npm run smoke:pack-install

- name: Smoke test packed Codex install path
if: steps.detect.outputs.cli_publish == 'true' || steps.detect.outputs.codex_publish == 'true'
run: npm run smoke:codex-pack-install

- name: Verify codex-plugin tarball peerDep is a concrete range
if: steps.detect.outputs.codex_publish == 'true'
run: |
Expand All @@ -94,6 +91,21 @@ jobs:
echo "OK: codex-plugin peerDep = '$PEER'"
rm -f "/tmp/$TARBALL"

- name: Verify openclaw-skill tarball peerDep is a concrete range
if: steps.detect.outputs.openclaw_publish == 'true'
run: |
TARBALL=$(npm pack -w @switchbot/openclaw-skill --pack-destination /tmp/ 2>&1 | tail -1)
PEER=$(tar -xOzf "/tmp/$TARBALL" package/package.json | node -e "
const p = JSON.parse(require('fs').readFileSync(0, 'utf8'));
console.log(p.peerDependencies?.['@switchbot/openapi-cli'] || '');
")
if [ -z "$PEER" ] || echo "$PEER" | grep -q "workspace:"; then
echo "FAIL: openclaw-skill peerDep is missing or unrewritten workspace:* — got: '$PEER'"
exit 1
fi
echo "OK: openclaw-skill peerDep = '$PEER'"
rm -f "/tmp/$TARBALL"

- name: Publish root CLI to npm
if: steps.detect.outputs.cli_publish == 'true'
run: npm publish --provenance --access public
Expand All @@ -108,7 +120,20 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish openclaw-skill to npm
id: publish_openclaw
if: steps.detect.outputs.openclaw_publish == 'true'
continue-on-error: true
run: npm publish -w @switchbot/openclaw-skill --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Annotate plugin publish failures
if: steps.detect.outputs.codex_publish == 'true' && steps.publish_codex.outcome == 'failure'
run: |
echo "::warning::codex-plugin publish step failed; root CLI promotion is unaffected. Investigate before next release."

- name: Annotate OpenClaw plugin publish failures
if: steps.detect.outputs.openclaw_publish == 'true' && steps.publish_openclaw.outcome == 'failure'
run: |
echo "::warning::openclaw-skill publish step failed; root CLI promotion is unaffected. Investigate before next release."
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed

- **OpenClaw plugin publish path** — `@switchbot/openclaw-skill` is back in the monorepo npm publish matrix. `publish.yml` now version-checks and publishes it alongside the CLI and Codex plugin, while `npm-published-smoke.yml` verifies the published tarball through the shared plugin smoke path.
- **OpenClaw package metadata** — `packages/openclaw-skill/README.md`, `.mcp.json`, and package metadata now describe the actual runtime contract: OpenClaw bootstraps via `bin/start.js`, then delegates to `switchbot mcp serve` for the CLI-owned MCP tool surface.

## [3.7.3]

### Added
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,19 @@
"start": "node dist/index.js",
"smoke:pack-install": "node scripts/smoke-pack-install.mjs",
"smoke:codex-pack-install": "node scripts/smoke-codex-pack-install.mjs",
"smoke:codex-git-sparse": "node scripts/smoke-codex-git-sparse.mjs",
"smoke:codex-temp-prefix-route-a": "node scripts/smoke-codex-temp-prefix-route-a.mjs",
"test": "vitest run",
"test:workspaces": "npm test --workspaces --if-present",
"test:all": "npm test && npm run test:workspaces",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:release-smoke:manual": "npm test -- tests/commands/policy.test.ts tests/commands/devices.test.ts tests/commands/explain.test.ts tests/commands/doctor.test.ts tests/commands/mcp.test.ts tests/commands/health-check.test.ts tests/commands/quota.test.ts tests/commands/status-sync.test.ts tests/status-sync/smoke.test.ts tests/commands/watch.test.ts tests/commands/events.test.ts tests/devices/catalog-fidelity.test.ts tests/commands/schema.test.ts tests/commands/auth.test.ts tests/commands/config.test.ts tests/commands/scenes.test.ts tests/commands/batch.test.ts tests/commands/history.test.ts tests/commands/expand.test.ts tests/commands/webhook.test.ts tests/commands/daemon.test.ts tests/commands/upgrade-check.test.ts tests/commands/install.test.ts tests/commands/uninstall.test.ts tests/commands/rules.test.ts tests/commands/plan.test.ts",
"verify:pre-commit": "npm run build && npm test -- tests/version.test.ts",
"verify:pre-push": "npm run build && npm test -- tests/version.test.ts && npm run smoke:pack-install",
"verify:pre-commit": "npm run build && npm test -- tests/version.test.ts tests/install/codex-checks.test.ts tests/commands/codex.test.ts && npm run test:workspaces",
"verify:release-gate": "npm run build && npm test -- tests/version.test.ts tests/install/codex-checks.test.ts tests/commands/codex.test.ts && npm run test:workspaces && npm run smoke:pack-install && npm run smoke:codex-pack-install && npm run smoke:codex-git-sparse && npm run smoke:codex-temp-prefix-route-a",
"verify:pre-push": "npm run verify:release-gate",
"verify:release": "node scripts/verify-release.mjs",
"prepublishOnly": "npm test && npm run build && npm run smoke:pack-install && npm run smoke:codex-pack-install"
"prepublishOnly": "npm run verify:release-gate"
},
"dependencies": {
"axios": "^1.7.9",
Expand Down
15 changes: 15 additions & 0 deletions packages/codex-plugin/.claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "switchbot",
"plugins": [
{
"name": "switchbot",
"source": "./plugins/switchbot",
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
Loading
Loading