Skip to content

fix(team): make worker startup acknowledgement durable #4651

fix(team): make worker startup acknowledgement durable

fix(team): make worker startup acknowledgement durable #4651

Workflow file for this run

name: CI
on:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
lint-and-typecheck:
name: Lint & Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Type check
run: npx tsc --noEmit
- name: Lint
run: npm run lint --if-present
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run functional tests
run: npm test -- --run
- name: Run subagent-lock performance test
run: npm exec vitest -- run tests/perf/subagent-lock.bench.ts --fileParallelism=false --maxWorkers=1
test-windows:
name: Test (Windows path suite)
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
# Scoped to the cross-platform path/encoding suites on a real Windows
# runner. The ubuntu-only `test` job exercises POSIX separators, so
# forward-slash assumptions in project-dir encoding and worktree
# transcript resolution (see #3274, #3276) can slip through it. Running
# the full `npm test` suite here is not yet possible: it has pre-existing
# platform-specific failures on Windows (e.g. python-repl sandbox, lsp
# devcontainer, session-end path interpolation) that are out of scope for
# this gate. Keep this list in sync with the path-handling test files.
- name: Run Windows path-handling tests
run: >-
npx vitest run
src/utils/__tests__/encode-project-path.test.ts
src/__tests__/resolve-transcript-path.test.ts
src/__tests__/session-history-search.test.ts
src/cli/__tests__/session-search.test.ts
src/lib/__tests__/worktree-paths.test.ts
src/hooks/project-memory/__tests__/hot-path-tracker.test.ts
src/hooks/merge-readiness/__tests__/win-cross-platform.test.ts
src/hooks/merge-readiness/__tests__/runtime.test.ts
src/hooks/merge-readiness/__tests__/tool-flow.test.ts
src/__tests__/windows-prompt-hook-runner.test.ts
src/installer/__tests__/claude-md-transaction.test.ts
src/team/__tests__/cli-detection.windows.integration.test.ts
build:
name: Build
runs-on: ubuntu-latest
needs: [lint-and-typecheck, test]
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Verify committed plugin shipping surface
run: npm run plugin:shipping:verify
- name: Build
run: npm run build
- name: Verify bridge registers all merge-readiness tools (source/packaged parity)
run: |
set -e
for tool in merge_readiness_start merge_readiness_set_content merge_readiness_record_answer merge_readiness_report merge_readiness_cancel; do
if ! grep -q "\"$tool\"" bridge/mcp-server.cjs; then
echo "::error::Packaged bridge/mcp-server.cjs is missing tool: $tool. Source/packaged parity broken (run npm run build)."
exit 1
fi
echo "bridge registers $tool"
done
- name: Check dist size
run: |
DIST_SIZE=$(du -sm dist | cut -f1)
echo "📦 Dist size: ${DIST_SIZE}MB"
if [ "$DIST_SIZE" -gt 50 ]; then
echo "⚠️ Warning: dist folder is larger than 50MB!"
fi
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 7
no-committed-build-artifacts:
name: No Committed Build Artifacts
runs-on: ubuntu-latest
# This candidate-side classifier is credential-free containment only; it
# never authorizes generated artifacts or supplies merge approval.
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Hold candidate generated changes
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: node scripts/ci/check-no-committed-build-artifacts.mjs --base "$BASE_SHA" --head "$HEAD_SHA"
multirepo-paths-gate:
name: Multi-repo Path Gate (AST-grep)
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Check for raw .omc path constructions
run: node scripts/ci/check-multirepo-paths.mjs
version-check:
name: Version Consistency Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Check version consistency
run: |
PKG_VERSION=$(node -p "require('./package.json').version")
PLUGIN_VERSION=$(node -p "require('./.claude-plugin/plugin.json').version")
MARKET_VERSION=$(node -p "require('./.claude-plugin/marketplace.json').version")
echo "package.json: $PKG_VERSION"
echo ".claude-plugin/plugin.json: $PLUGIN_VERSION"
echo ".claude-plugin/marketplace.json: $MARKET_VERSION"
if [ "$PKG_VERSION" != "$PLUGIN_VERSION" ] || [ "$PKG_VERSION" != "$MARKET_VERSION" ]; then
echo ""
echo "❌ Version mismatch!"
echo " package.json: $PKG_VERSION"
echo " plugin.json: $PLUGIN_VERSION"
echo " marketplace.json: $MARKET_VERSION"
echo ""
echo "All three files must have the same version."
exit 1
fi
echo "✅ All versions match: $PKG_VERSION"
npm-pack-test:
name: npm pack + install test
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: npm pack test
run: |
echo "📦 Creating tarball..."
npm pack
TARBALL=$(ls -t oh-my-claude-sisyphus-*.tgz | head -1)
echo "📦 Tarball: $TARBALL"
echo "🔎 Verifying the packaged MCP bridge registers every merge-readiness tool..."
for tool in merge_readiness_start merge_readiness_set_content merge_readiness_record_answer merge_readiness_report merge_readiness_cancel; do
if ! tar -xOf "$TARBALL" package/bridge/mcp-server.cjs | grep -q "\"$tool\""; then
echo "::error::npm package bridge/mcp-server.cjs is missing tool: $tool"
exit 1
fi
echo "packaged bridge registers $tool"
done
# ENOTEMPTY hardening (mirrors .github/workflows/upgrade-test.yml):
# the global node_modules dir is reused across runs on GitHub-hosted
# runners and inside the GitHub-hosted tool cache. A previously
# interrupted `npm install -g` can leave the resolved package dir
# and/or npm's staging temp dirs (`.oh-my-claude-sisyphus-*`) behind,
# so the next install fails with
# npm ERR! ENOTEMPTY: directory not empty, rename
# '.../oh-my-claude-sisyphus' -> '.../.oh-my-claude-sisyphus-XXXX'
# Remove any stale global package + npm staging dirs before
# installing, then retry a few times so a transient rename race does
# not fail the run. A persistent install failure still exits non-zero.
PKG=oh-my-claude-sisyphus
GLOBAL_ROOT="$(npm root -g)"
clean_stale_global_pkg() {
# `:?` guards against an empty GLOBAL_ROOT so we never rm -rf "/".
rm -rf "${GLOBAL_ROOT:?}/$PKG" 2>/dev/null || true
find "$GLOBAL_ROOT" -maxdepth 1 -name ".$PKG-*" -exec rm -rf {} + 2>/dev/null || true
}
echo "📦 Testing global install from tarball..."
clean_stale_global_pkg
ATTEMPTS=3
INSTALLED=false
for attempt in $(seq 1 "$ATTEMPTS"); do
echo "Installing $TARBALL globally (attempt $attempt/$ATTEMPTS)"
if npm install -g "./$TARBALL" --no-audit --no-fund; then
INSTALLED=true
break
fi
echo "Install attempt $attempt failed; cleaning stale global state and retrying."
clean_stale_global_pkg
sleep 2
done
if [ "$INSTALLED" != "true" ]; then
echo "❌ npm install -g ./$TARBALL failed after $ATTEMPTS attempts"
exit 1
fi
echo "🔍 Checking omc command..."
which omc
echo "🔍 Testing omc --version..."
omc --version
VERSION_OUTPUT=$(omc --version 2>&1)
if [ $? -ne 0 ]; then
echo "❌ omc --version failed!"
echo "$VERSION_OUTPUT"
exit 1
fi
echo "✅ omc --version: $VERSION_OUTPUT"
echo "🔍 Testing omc --help..."
omc --help
HELP_OUTPUT=$(omc --help 2>&1)
if [ $? -ne 0 ]; then
echo "❌ omc --help failed!"
echo "$HELP_OUTPUT"
exit 1
fi
echo "✅ npm pack + install test passed!"