raidlock 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {raidlock-0.1.0 → raidlock-0.1.1}/.claude-plugin/marketplace.json +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/.claude-plugin/plugin.json +8 -2
- raidlock-0.1.1/.github/pull_request_template.md +11 -0
- raidlock-0.1.1/.github/workflows/ci.yml +94 -0
- raidlock-0.1.1/.github/workflows/docker.yml +42 -0
- raidlock-0.1.1/.github/workflows/release.yml +112 -0
- raidlock-0.1.1/.github/workflows/scorecard.yml +31 -0
- raidlock-0.1.1/.github/workflows/web.yml +47 -0
- raidlock-0.1.1/.release-please-manifest.json +3 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/CHANGELOG.md +16 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/CONTRIBUTING.md +2 -2
- {raidlock-0.1.0 → raidlock-0.1.1}/PKG-INFO +20 -14
- {raidlock-0.1.0 → raidlock-0.1.1}/README.md +19 -13
- {raidlock-0.1.0 → raidlock-0.1.1}/SECURITY.md +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/agents/raid-worker.md +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/README.md +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/brand/raidlock-lockup-dark.svg +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/brand/raidlock-lockup.svg +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/brand/raidlock-mark-dark.svg +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/brand/raidlock-mark.svg +1 -1
- raidlock-0.1.1/docs/assets/brand/social-preview.png +0 -0
- raidlock-0.1.1/docs/assets/brand/social-preview.svg +1 -0
- raidlock-0.1.1/docs/assets/demo.webp +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/benchmark.md +2 -2
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/docker.md +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/pyproject.toml +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/release-please-config.json +5 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/scripts/docker-smoke.sh +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/__init__.py +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/lead.py +1 -1
- raidlock-0.1.1/src/raidlock/web/static/icon-32.png +0 -0
- raidlock-0.1.1/src/raidlock/web/static/icon.svg +1 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/test_hook_interpreter.py +3 -3
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_runner_security.py +1 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/uv.lock +1 -1
- raidlock-0.1.0/.github/pull_request_template.md +0 -13
- raidlock-0.1.0/.github/workflows/ci.yml +0 -175
- raidlock-0.1.0/.github/workflows/docker-publish.yml +0 -63
- raidlock-0.1.0/.github/workflows/release-please.yml +0 -19
- raidlock-0.1.0/.github/workflows/release.yml +0 -118
- raidlock-0.1.0/.release-please-manifest.json +0 -3
- raidlock-0.1.0/docs/assets/brand/social-preview.png +0 -0
- raidlock-0.1.0/docs/assets/brand/social-preview.svg +0 -1
- raidlock-0.1.0/docs/assets/demo.gif +0 -0
- raidlock-0.1.0/src/raidlock/web/static/icon-32.png +0 -0
- raidlock-0.1.0/src/raidlock/web/static/icon.svg +0 -1
- {raidlock-0.1.0 → raidlock-0.1.1}/.dockerignore +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.github/CODEOWNERS +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.github/ISSUE_TEMPLATE/runner_adapter.yml +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.github/dependabot.yml +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.github/workflows/pr-title.yml +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.gitignore +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/.gitleaks.toml +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/CODE_OF_CONDUCT.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/Dockerfile +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/LICENSE +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/PROTOCOL.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/bin/raid +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/bin/raidlock +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/ARCHITECTURE.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/RELEASING.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/brand/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/brand/raidlock-mark-mono.svg +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/brand/raidlock-wordmark-dark.svg +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/brand/raidlock-wordmark.svg +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/demo-60s.cast +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/hero.gif +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/hero.mp4 +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-plain-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-plain-mobile.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-plain-overview-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-plain-overview-mobile.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-achievements-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-frames-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-graph-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-map-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-mobile.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-overview-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-overview-mobile.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/assets/ui-raid-replay-desktop.png +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/commands.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/concepts.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/foresight.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/getting-started.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/hooks.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/install.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/lead-playbook.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/limits.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/lore.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/mcp.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/multi-provider.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/native.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/operations.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/orchestration.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/overview.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/planning.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/pr.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/ui.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/verification.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/docs/guides/worker-rules.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/claude-only/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/claude-plus-codex/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/demo/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/demo/builder.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/demo/record.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/demo/run.sh +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/docker/compose.yaml +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/multi-workspace/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/playground/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/examples/playground/setup.sh +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/hooks/hooks.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/scripts/bench_overhead.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/scripts/curate-public.sh +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/scripts/demo-60s.sh +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/scripts/demo-tape-setup.sh +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/scripts/demo.tape +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/scripts/overhead_ab.sh +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/scripts/render-hero.sh +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/skills/raid/SKILL.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/skills/raidlock/SKILL.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/skills/raidlock/reference/commands.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/skills/raidlock/reference/hooks.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/skills/raidlock/reference/lead.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/__main__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/_python.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/achievements.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/approvals.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/bench.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/bridge/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/budgets.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/cli.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/commands_install.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/advisories.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/billing.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/board.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/brief.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/clock.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/cost.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/db.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/errors.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/exe.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/hints.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/identity.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/lead_env.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/lead_hook.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/leases.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/lock.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/messages.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/migrate.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/model.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/models.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/paths.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/portable.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/receipts.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/registry.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/repos.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/safeio.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/status.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/store.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/tokens.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/core/transcript.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/duel.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/foresight.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/frames.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/gitguard.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/guard.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/hooks.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/infer.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/limits.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/lore/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/lore/approval.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/lore/capture.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/lore/cli.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/lore/distill.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/lore/frontmatter.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/lore/inject.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/lore/vault.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/mcp/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/mcp/resources.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/mcp/server.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/mcp/tools.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/notify.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/party.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/pr.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/prsync.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/recipes/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/recipes/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/recipes/docs-refresh.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/recipes/multi-repo-refactor.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/recipes/security-audit.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/recipes/upgrade-deps.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/reputation.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/resume.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/resurrect.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/routing.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/base.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/brief.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/claude_code.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/cli.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/codex.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/gemini.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/isolation.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/policy.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/runner.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/shell.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/verifycache.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/runners/workspace.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/scan.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/snapshot.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/treasury.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/tui.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/achievements/view.css +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/achievements/view.js +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/bosses/view.css +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/bosses/view.js +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/cli.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/data.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/export.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/frames/view.css +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/frames/view.js +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/graph/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/graph/view.css +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/graph/view.js +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/raidmap/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/raidmap/view.css +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/raidmap/view.js +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/replay/__init__.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/replay/view.css +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/replay/view.js +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/server.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/static/app.css +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/static/app.js +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/static/fonts/OFL.txt +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/static/fonts/cinzel-600.woff2 +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/static/fonts/cinzel-700.woff2 +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/static/icon-raid.svg +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/src/raidlock/web/static/index.html +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/achievements/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/achievements/test_achievements.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/approvals/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/approvals/test_approvals.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/bench/budget.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/bench/test_overhead.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/budgets/test_budgets.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/corehelpers.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_advisories.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_brief_untrusted.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_bug_sweep.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_cli.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_cli_extensions.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_cli_safe_credentials.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_cli_team.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_cli_ux.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_concurrency.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_cost.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_db_initialization.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_handover_security.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_identity.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_lead_token.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_leases.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_long_loops.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_messages.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_migration.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_model.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_multi_agent_collaboration.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_paths.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_portable.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_process_anchor.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_release_audit.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_safeio.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_scale.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_status_registry.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_store_lock.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_transcript.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_transcript_events.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_ui_host.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_verification_membership.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_verify_cache.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/core/test_verify_receipts.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/duel/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/duel/test_duel.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/e2e/test_demo.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/enforce/README.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/enforce/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/enforce/test_must_not.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/examples/test_demo_60s.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/examples/test_playground.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/extras/test_notify_snapshot.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/.gitattributes +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/LOG.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/agents.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/cards/active.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/cards/checking.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/cards/finished.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/cards/first.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/cards/queued.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/cards/second.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/cards/waiting.md +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/inbox/w-one.jsonl +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/inbox/worker.jsonl +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/leases.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/settings.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/fixtures/v1-board/teams.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/foresight/test_foresight.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/frames/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/frames/test_frames.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/guard/test_guard.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/guard/test_guard_security.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/post_claim.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_bash_board_write.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_bash_plain.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_bash_subagent_done.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_write_allow.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_write_board_file.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_write_main_free.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_write_main_held.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_write_no_task.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_write_notebook.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/pre_write_other_fence.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/session_start.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/fixtures/subagent_stop.json +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/test_compound_targets.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/test_git_guard.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/test_hook_security.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/test_hooks.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/test_install_commands.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/test_native_bridge.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/hooks/test_separate_session_worker.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/infer/test_infer.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/limits/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/limits/test_limits.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/lore/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/lore/lorehelpers.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/lore/test_lore_approval.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/lore/test_lore_capture.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/lore/test_lore_inject.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/lore/test_lore_vault.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/mcp/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/mcp/mcphelpers.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/mcp/test_mcp_protocol.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/mcp/test_mcp_resources.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/mcp/test_mcp_tools.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/mcp/test_mcp_workspace.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/party/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/party/test_party.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/portable.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/pr/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/pr/prhelpers.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/pr/test_pr.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/prsync/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/prsync/test_prsync.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/recipes/test_recipes.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/reputation/test_reputation.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/resume/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/resume/test_resume.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/resurrect/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/resurrect/fake_claude.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/resurrect/test_resurrect.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/routing/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/routing/test_routing.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/fake_agent.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/fixtures/claude_read_only.jsonl +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/fixtures/codex_read_only.jsonl +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/fixtures/codex_workspace_write.jsonl +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/runhelpers.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_recovery_integration.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_runner_adapters.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_runner_brief.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_runner_delegate.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_runner_live.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_runner_policy.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_sensitive_disposal.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/runners/test_verify_cleanup.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/scan/fixtures/paths.patch +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/scan/fixtures/secrets.patch +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/scan/test_scan.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/treasury/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/treasury/test_nonfinite.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/treasury/test_treasury.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/tui/empty.txt +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/tui/populated.txt +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/tui/test_tui.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/browser.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/conftest.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/demo.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/fxfeed.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/graph/test_graph.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/layout_states.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/party/test_party_web.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/raidmap/test_raidmap.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/replay/test_replay.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/serving.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_approvals_web.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_focus_view.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_fx.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_layout_browser.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_layout_logic.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_pr_pill.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_web_browser.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_web_fds.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_web_features.py +0 -0
- {raidlock-0.1.0 → raidlock-0.1.1}/tests/web/test_web_server.py +0 -0
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"name": "raidlock",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Lease-and-review board for coding agents: path locks enforced by hooks, a lead-only done gate, heartbeats and handbacks.",
|
|
15
|
-
"version": "0.1.
|
|
15
|
+
"version": "0.1.1",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "agi1clj"
|
|
18
18
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "raidlock",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Lease-and-review board for coding agents: path locks enforced by hooks, a lead-only done gate, heartbeats and handbacks.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "agi1clj",
|
|
@@ -9,5 +9,11 @@
|
|
|
9
9
|
"homepage": "https://github.com/agi1clj/raidlock",
|
|
10
10
|
"repository": "https://github.com/agi1clj/raidlock",
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"keywords": [
|
|
12
|
+
"keywords": [
|
|
13
|
+
"agents",
|
|
14
|
+
"coordination",
|
|
15
|
+
"leases",
|
|
16
|
+
"locks",
|
|
17
|
+
"review"
|
|
18
|
+
]
|
|
13
19
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## What
|
|
2
|
+
|
|
3
|
+
## How to verify
|
|
4
|
+
|
|
5
|
+
## Checklist
|
|
6
|
+
|
|
7
|
+
- [ ] PR title follows Conventional Commits (`feat:`, `fix:`, `docs:`...); it becomes the changelog entry
|
|
8
|
+
- [ ] Commits signed off (`git commit -s`)
|
|
9
|
+
- [ ] Tests added or updated; `uv run pytest -n auto` passes
|
|
10
|
+
- [ ] Docs updated if behavior changed (README, docs/guides, PROTOCOL.md, skills)
|
|
11
|
+
- [ ] No new runtime dependency, no secrets or real board data, actions pinned to commit SHAs
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths-ignore: ["docs/**", "**.md"]
|
|
7
|
+
pull_request:
|
|
8
|
+
paths-ignore: ["docs/**", "**.md"]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ci-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
PYTHONUTF8: "1"
|
|
20
|
+
UV_NO_PROGRESS: "1"
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
actionlint:
|
|
24
|
+
name: actionlint
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 5
|
|
27
|
+
env:
|
|
28
|
+
ACTIONLINT_VERSION: 1.7.12
|
|
29
|
+
ACTIONLINT_SHA256: 8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
32
|
+
with:
|
|
33
|
+
persist-credentials: false
|
|
34
|
+
- name: Install actionlint
|
|
35
|
+
run: |
|
|
36
|
+
archive="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
|
|
37
|
+
curl -fsSLo "$archive" "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/${archive}"
|
|
38
|
+
echo "${ACTIONLINT_SHA256} ${archive}" | sha256sum -c -
|
|
39
|
+
tar -xzf "$archive" actionlint
|
|
40
|
+
- name: Run actionlint
|
|
41
|
+
run: ./actionlint -color
|
|
42
|
+
|
|
43
|
+
test:
|
|
44
|
+
name: test (${{ matrix.os }}, py${{ matrix.python }})
|
|
45
|
+
runs-on: ${{ matrix.os }}
|
|
46
|
+
timeout-minutes: 30
|
|
47
|
+
strategy:
|
|
48
|
+
fail-fast: false
|
|
49
|
+
matrix:
|
|
50
|
+
include:
|
|
51
|
+
- os: ubuntu-latest
|
|
52
|
+
python: "3.11"
|
|
53
|
+
- os: macos-latest
|
|
54
|
+
python: "3.14"
|
|
55
|
+
defaults:
|
|
56
|
+
run:
|
|
57
|
+
shell: bash
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
60
|
+
with:
|
|
61
|
+
persist-credentials: false
|
|
62
|
+
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e
|
|
63
|
+
with:
|
|
64
|
+
enable-cache: true
|
|
65
|
+
python-version: ${{ matrix.python }}
|
|
66
|
+
- name: Run tests
|
|
67
|
+
run: uv run --locked --with pytest-xdist==3.8.0 pytest -n auto --ignore=tests/web
|
|
68
|
+
|
|
69
|
+
checks:
|
|
70
|
+
name: lint, types, overhead
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
timeout-minutes: 10
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
75
|
+
with:
|
|
76
|
+
persist-credentials: false
|
|
77
|
+
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e
|
|
78
|
+
with:
|
|
79
|
+
enable-cache: true
|
|
80
|
+
python-version: "3.11"
|
|
81
|
+
- name: Ruff lint
|
|
82
|
+
run: uv run --locked --with ruff==0.15.14 ruff check
|
|
83
|
+
- name: Ruff format
|
|
84
|
+
if: always()
|
|
85
|
+
run: uv run --locked --with ruff==0.15.14 ruff format --check
|
|
86
|
+
- name: Pyright
|
|
87
|
+
if: always()
|
|
88
|
+
run: uv run --locked --with pyright==1.1.408 pyright src/raidlock
|
|
89
|
+
- name: Measure idle overhead
|
|
90
|
+
if: always()
|
|
91
|
+
run: |
|
|
92
|
+
uv run --locked python scripts/bench_overhead.py --runs 5 --tokenizer estimate > overhead.json 2> overhead.md
|
|
93
|
+
head -n 1 overhead.md
|
|
94
|
+
cat overhead.md >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Docker
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths: ["Dockerfile", ".dockerignore", "pyproject.toml", "uv.lock", "src/**", "scripts/docker-smoke.sh", ".github/workflows/docker.yml"]
|
|
7
|
+
pull_request:
|
|
8
|
+
paths: ["Dockerfile", ".dockerignore", "pyproject.toml", "uv.lock", "src/**", "scripts/docker-smoke.sh", ".github/workflows/docker.yml"]
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: "17 6 * * 1"
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: docker-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
docker:
|
|
22
|
+
name: docker image
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
timeout-minutes: 20
|
|
25
|
+
env:
|
|
26
|
+
IMAGE: raidlock:ci
|
|
27
|
+
TRIVY_VERSION: 0.75.0
|
|
28
|
+
TRIVY_SHA256: c6e65abddb348e25f10549df887045629cf28cc72453cd1c63acb717316b3f3f
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
31
|
+
with:
|
|
32
|
+
persist-credentials: false
|
|
33
|
+
- name: Build image
|
|
34
|
+
run: docker build --platform linux/amd64 -t "$IMAGE" .
|
|
35
|
+
- name: Install Trivy
|
|
36
|
+
run: |
|
|
37
|
+
archive="trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz"
|
|
38
|
+
curl -fsSLo "$archive" "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/${archive}"
|
|
39
|
+
echo "${TRIVY_SHA256} ${archive}" | sha256sum -c -
|
|
40
|
+
tar -xzf "$archive" trivy
|
|
41
|
+
- name: Trivy image scan
|
|
42
|
+
run: ./trivy image --exit-code 1 --severity HIGH,CRITICAL --ignore-unfixed --no-progress "$IMAGE"
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
permissions: {}
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: release
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
|
|
13
|
+
env:
|
|
14
|
+
IMAGE: ghcr.io/agi1clj/raidlock
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
release-please:
|
|
18
|
+
name: Release PR and tag
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 10
|
|
21
|
+
permissions:
|
|
22
|
+
contents: write
|
|
23
|
+
pull-requests: write
|
|
24
|
+
outputs:
|
|
25
|
+
release_created: ${{ steps.rp.outputs.release_created }}
|
|
26
|
+
tag_name: ${{ steps.rp.outputs.tag_name }}
|
|
27
|
+
steps:
|
|
28
|
+
- id: rp
|
|
29
|
+
uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7
|
|
30
|
+
with:
|
|
31
|
+
token: ${{ github.token }}
|
|
32
|
+
config-file: release-please-config.json
|
|
33
|
+
manifest-file: .release-please-manifest.json
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
name: PyPI and signed release assets
|
|
37
|
+
needs: release-please
|
|
38
|
+
if: needs.release-please.outputs.release_created == 'true'
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
timeout-minutes: 15
|
|
41
|
+
environment:
|
|
42
|
+
name: pypi
|
|
43
|
+
url: https://pypi.org/p/raidlock
|
|
44
|
+
permissions:
|
|
45
|
+
contents: write
|
|
46
|
+
id-token: write
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
49
|
+
with:
|
|
50
|
+
ref: ${{ needs.release-please.outputs.tag_name }}
|
|
51
|
+
persist-credentials: false
|
|
52
|
+
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e
|
|
53
|
+
with:
|
|
54
|
+
python-version: "3.13"
|
|
55
|
+
- name: Build
|
|
56
|
+
run: uv build
|
|
57
|
+
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086
|
|
58
|
+
with:
|
|
59
|
+
attestations: true
|
|
60
|
+
- name: Sign and attach to the GitHub release
|
|
61
|
+
env:
|
|
62
|
+
GH_TOKEN: ${{ github.token }}
|
|
63
|
+
TAG: ${{ needs.release-please.outputs.tag_name }}
|
|
64
|
+
run: |
|
|
65
|
+
uvx --from sigstore==4.5.1 sigstore sign dist/*.tar.gz dist/*.whl
|
|
66
|
+
gh release upload "$TAG" dist/*.tar.gz dist/*.whl dist/*.sigstore.json --clobber
|
|
67
|
+
|
|
68
|
+
image:
|
|
69
|
+
name: Container image
|
|
70
|
+
needs: [release-please, publish]
|
|
71
|
+
if: needs.release-please.outputs.release_created == 'true'
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
timeout-minutes: 45
|
|
74
|
+
permissions:
|
|
75
|
+
contents: read
|
|
76
|
+
packages: write
|
|
77
|
+
id-token: write
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
80
|
+
with:
|
|
81
|
+
ref: ${{ needs.release-please.outputs.tag_name }}
|
|
82
|
+
persist-credentials: false
|
|
83
|
+
- name: Version from tag
|
|
84
|
+
env:
|
|
85
|
+
TAG: ${{ needs.release-please.outputs.tag_name }}
|
|
86
|
+
run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV"
|
|
87
|
+
- uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1
|
|
88
|
+
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069
|
|
89
|
+
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f
|
|
90
|
+
with:
|
|
91
|
+
registry: ghcr.io
|
|
92
|
+
username: ${{ github.actor }}
|
|
93
|
+
password: ${{ github.token }}
|
|
94
|
+
- name: Build and push
|
|
95
|
+
id: build
|
|
96
|
+
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc
|
|
97
|
+
with:
|
|
98
|
+
context: .
|
|
99
|
+
platforms: linux/amd64,linux/arm64
|
|
100
|
+
push: true
|
|
101
|
+
sbom: true
|
|
102
|
+
provenance: mode=max
|
|
103
|
+
tags: |
|
|
104
|
+
${{ env.IMAGE }}:${{ env.VERSION }}
|
|
105
|
+
${{ env.IMAGE }}:latest
|
|
106
|
+
- uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6
|
|
107
|
+
with:
|
|
108
|
+
cosign-release: v3.1.3
|
|
109
|
+
- name: Sign image
|
|
110
|
+
env:
|
|
111
|
+
DIGEST: ${{ steps.build.outputs.digest }}
|
|
112
|
+
run: cosign sign --yes "${IMAGE}@${DIGEST}"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Scorecard
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: "23 5 * * 1"
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions: read-all
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
analysis:
|
|
14
|
+
name: OpenSSF Scorecard
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
timeout-minutes: 10
|
|
17
|
+
permissions:
|
|
18
|
+
security-events: write
|
|
19
|
+
id-token: write
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
- uses: ossf/scorecard-action@fa7117db83c52d787ae5a89f350999701505d78e
|
|
25
|
+
with:
|
|
26
|
+
results_file: results.sarif
|
|
27
|
+
results_format: sarif
|
|
28
|
+
publish_results: true
|
|
29
|
+
- uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370
|
|
30
|
+
with:
|
|
31
|
+
sarif_file: results.sarif
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Web UI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths: ["src/raidlock/web/**", "tests/web/**", "uv.lock", ".github/workflows/web.yml"]
|
|
7
|
+
pull_request:
|
|
8
|
+
paths: ["src/raidlock/web/**", "tests/web/**", "uv.lock", ".github/workflows/web.yml"]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: web-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
PYTHONUTF8: "1"
|
|
20
|
+
UV_NO_PROGRESS: "1"
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
playwright:
|
|
24
|
+
name: web UI (Playwright)
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 20
|
|
27
|
+
container:
|
|
28
|
+
image: mcr.microsoft.com/playwright/python:v1.64.0-noble@sha256:684df257a1fa0ef3fa288239819984008f560e8f8db5b635ee9e2a50cbcd2e23
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
31
|
+
with:
|
|
32
|
+
persist-credentials: false
|
|
33
|
+
- uses: astral-sh/setup-uv@07a047e608db84b3d8c06cd9a7c7dcc9c355c18e
|
|
34
|
+
with:
|
|
35
|
+
enable-cache: true
|
|
36
|
+
python-version: "3.13"
|
|
37
|
+
- name: Run web tests
|
|
38
|
+
run: uv run --locked --extra ui-test --with pytest-xdist==3.8.0 pytest -n auto tests/web
|
|
39
|
+
- name: Upload traces on failure
|
|
40
|
+
if: failure()
|
|
41
|
+
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9
|
|
42
|
+
with:
|
|
43
|
+
name: playwright-results
|
|
44
|
+
path: test-results/
|
|
45
|
+
if-no-files-found: ignore
|
|
46
|
+
retention-days: 7
|
|
47
|
+
|
|
@@ -4,6 +4,22 @@ All notable changes to this project are documented here.
|
|
|
4
4
|
|
|
5
5
|
The format follows [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/), and the project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.1.1](https://github.com/agi1clj/raidlock/compare/v0.1.0...v0.1.1) (2026-10-27)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* **types:** treat a missing lease age as zero ([af86a4d](https://github.com/agi1clj/raidlock/commit/af86a4dc34f2833a4d9c21a57398f2a0c0141c45))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Documentation
|
|
16
|
+
|
|
17
|
+
* centered header with badges under the pitch ([501cdc2](https://github.com/agi1clj/raidlock/commit/501cdc2063fc16ebe59ec5c6de230da973d2d75d))
|
|
18
|
+
* one title, the logo ([4ce8f35](https://github.com/agi1clj/raidlock/commit/4ce8f3572375ff3f98d4768b7aeda9e8cb85ee9a))
|
|
19
|
+
* raid theme note; gold logo, favicon and social preview ([7bfbb13](https://github.com/agi1clj/raidlock/commit/7bfbb1338668b1b3b2b5d361e94324fa493095ec))
|
|
20
|
+
* sharper UI tour as animated WebP ([6aee151](https://github.com/agi1clj/raidlock/commit/6aee151dd2b95f785e510b2b65d8d5990c079e8a))
|
|
21
|
+
* short PR template ([14402b9](https://github.com/agi1clj/raidlock/commit/14402b92dee168bf5bdbcffa7d2d69917e9d988f))
|
|
22
|
+
|
|
7
23
|
## [Unreleased]
|
|
8
24
|
|
|
9
25
|
## [0.1.0] - 2026-10-27
|
|
@@ -49,7 +49,7 @@ uv run --locked playwright install chromium
|
|
|
49
49
|
uv run --locked pytest tests/web
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
Tests must pass on Linux and macOS with Python 3.11
|
|
52
|
+
Tests must pass on Linux and macOS with Python 3.11 and newer. The recovered lead lease requires process-anchor verification, which reads Toolhelp on Windows but is not verified there, so native Windows is a release limitation; use WSL2.
|
|
53
53
|
|
|
54
54
|
Every bug fix comes with a test that fails without the fix. Concurrency and path-canonicalization code also gets property tests with Hypothesis.
|
|
55
55
|
|
|
@@ -128,7 +128,7 @@ See [the release guide](docs/RELEASING.md) for publication gates, token setup, v
|
|
|
128
128
|
|
|
129
129
|
## Python checks
|
|
130
130
|
|
|
131
|
-
CI tests Python 3.11
|
|
131
|
+
CI tests the oldest supported Python (3.11) on Linux and the newest (3.14) on macOS, and runs ruff, pyright and actionlint. The Playwright UI suite runs when the web UI changes; the container build, smoke test and Trivy scan run when the image inputs change and weekly.
|
|
132
132
|
Run the same static checks locally:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: raidlock
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Local-first lease-and-review board for coding agents from any provider
|
|
5
5
|
Project-URL: Homepage, https://github.com/agi1clj/raidlock
|
|
6
6
|
Project-URL: Documentation, https://github.com/agi1clj/raidlock/tree/main/docs/guides
|
|
@@ -31,22 +31,24 @@ Requires-Dist: pytest-playwright>=0.5; extra == 'ui-test'
|
|
|
31
31
|
Requires-Dist: pytest>=8; extra == 'ui-test'
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
33
33
|
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
<p align="center">
|
|
35
|
+
<picture>
|
|
36
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/brand/raidlock-lockup-dark.svg">
|
|
37
|
+
<img src="docs/assets/brand/raidlock-lockup.svg" alt="raidlock" width="227" height="42">
|
|
38
|
+
</picture>
|
|
39
|
+
</p>
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
<p align="center"><b>raidlock stops parallel coding agents from overwriting each other's files, across Claude Code, Codex and Gemini, and won't accept their work until the tests pass and an agent from another provider signs off.</b></p>
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
<p align="center">
|
|
44
|
+
<a href="https://github.com/agi1clj/raidlock/actions/workflows/ci.yml"><img src="https://github.com/agi1clj/raidlock/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
|
|
45
|
+
<a href="https://pypi.org/project/raidlock/"><img src="https://img.shields.io/pypi/v/raidlock" alt="PyPI"></a>
|
|
46
|
+
<a href="https://pypi.org/project/raidlock/"><img src="https://img.shields.io/pypi/pyversions/raidlock" alt="Python"></a>
|
|
47
|
+
<a href="https://scorecard.dev/viewer/?uri=github.com/agi1clj/raidlock"><img src="https://api.scorecard.dev/projects/github.com/agi1clj/raidlock/badge" alt="OpenSSF Scorecard"></a>
|
|
48
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"></a>
|
|
49
|
+
</p>
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<p align="center"><img src="docs/assets/demo.gif" alt="raidlock web UI tour" width="960"></p>
|
|
46
|
-
|
|
47
|
-
[](https://github.com/agi1clj/raidlock/actions/workflows/ci.yml)
|
|
48
|
-
[](https://pypi.org/project/raidlock/)
|
|
49
|
-
[](LICENSE)
|
|
51
|
+
<p align="center"><img src="docs/assets/demo.webp" alt="raidlock web UI tour" width="960"></p>
|
|
50
52
|
|
|
51
53
|
Run Claude Code, Codex, Gemini, shell scripts and people on one board. Each piece of work is a card. Claiming a card leases the exact paths it may touch, and hooks refuse edits anywhere else. One lead closes cards, and only after a signed verify receipt exists for the commit and, on a mixed-provider board, a reviewer from another provider has approved. You can follow who is doing what in the terminal or in a raid-themed web UI.
|
|
52
54
|
|
|
@@ -173,6 +175,10 @@ Gemini runs only through `raid delegate --to gemini`, and that adapter is tested
|
|
|
173
175
|
|
|
174
176
|
If you are an agent, start with [skills/raidlock/SKILL.md](skills/raidlock/SKILL.md).
|
|
175
177
|
|
|
178
|
+
## Why "raid"
|
|
179
|
+
|
|
180
|
+
Running several agents feels like leading a raid in an MMO such as World of Warcraft: a raid leader assigns the party, each member holds a role, big quests become bosses, and nobody loots until the boss is down. raidlock borrows that vocabulary for the web UI (guilds, quests, raid frames, boss board, feats). The CLI and the docs use plain terms. raidlock is not affiliated with or endorsed by Blizzard Entertainment.
|
|
181
|
+
|
|
176
182
|
## Security
|
|
177
183
|
|
|
178
184
|
raidlock keeps cooperating agents out of each other's way. It is not a sandbox. Tokens, the lead secret and the verify signing key are files under your user account, readable by any process running as you. `raid verify` runs only under bubblewrap on Linux or `sandbox-exec` on macOS. The UI listens on `127.0.0.1` and answers `GET` only. Threat model and reporting: [SECURITY.md](SECURITY.md). Limits: [Security and limits](docs/guides/overview.md#security-and-limits).
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
<
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/brand/raidlock-lockup-dark.svg">
|
|
4
|
+
<img src="docs/assets/brand/raidlock-lockup.svg" alt="raidlock" width="227" height="42">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
<p align="center"><b>raidlock stops parallel coding agents from overwriting each other's files, across Claude Code, Codex and Gemini, and won't accept their work until the tests pass and an agent from another provider signs off.</b></p>
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://github.com/agi1clj/raidlock/actions/workflows/ci.yml"><img src="https://github.com/agi1clj/raidlock/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
|
|
12
|
+
<a href="https://pypi.org/project/raidlock/"><img src="https://img.shields.io/pypi/v/raidlock" alt="PyPI"></a>
|
|
13
|
+
<a href="https://pypi.org/project/raidlock/"><img src="https://img.shields.io/pypi/pyversions/raidlock" alt="Python"></a>
|
|
14
|
+
<a href="https://scorecard.dev/viewer/?uri=github.com/agi1clj/raidlock"><img src="https://api.scorecard.dev/projects/github.com/agi1clj/raidlock/badge" alt="OpenSSF Scorecard"></a>
|
|
15
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"></a>
|
|
16
|
+
</p>
|
|
9
17
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<p align="center"><img src="docs/assets/demo.gif" alt="raidlock web UI tour" width="960"></p>
|
|
13
|
-
|
|
14
|
-
[](https://github.com/agi1clj/raidlock/actions/workflows/ci.yml)
|
|
15
|
-
[](https://pypi.org/project/raidlock/)
|
|
16
|
-
[](LICENSE)
|
|
18
|
+
<p align="center"><img src="docs/assets/demo.webp" alt="raidlock web UI tour" width="960"></p>
|
|
17
19
|
|
|
18
20
|
Run Claude Code, Codex, Gemini, shell scripts and people on one board. Each piece of work is a card. Claiming a card leases the exact paths it may touch, and hooks refuse edits anywhere else. One lead closes cards, and only after a signed verify receipt exists for the commit and, on a mixed-provider board, a reviewer from another provider has approved. You can follow who is doing what in the terminal or in a raid-themed web UI.
|
|
19
21
|
|
|
@@ -140,6 +142,10 @@ Gemini runs only through `raid delegate --to gemini`, and that adapter is tested
|
|
|
140
142
|
|
|
141
143
|
If you are an agent, start with [skills/raidlock/SKILL.md](skills/raidlock/SKILL.md).
|
|
142
144
|
|
|
145
|
+
## Why "raid"
|
|
146
|
+
|
|
147
|
+
Running several agents feels like leading a raid in an MMO such as World of Warcraft: a raid leader assigns the party, each member holds a role, big quests become bosses, and nobody loots until the boss is down. raidlock borrows that vocabulary for the web UI (guilds, quests, raid frames, boss board, feats). The CLI and the docs use plain terms. raidlock is not affiliated with or endorsed by Blizzard Entertainment.
|
|
148
|
+
|
|
143
149
|
## Security
|
|
144
150
|
|
|
145
151
|
raidlock keeps cooperating agents out of each other's way. It is not a sandbox. Tokens, the lead secret and the verify signing key are files under your user account, readable by any process running as you. `raid verify` runs only under bubblewrap on Linux or `sandbox-exec` on macOS. The UI listens on `127.0.0.1` and answers `GET` only. Threat model and reporting: [SECURITY.md](SECURITY.md). Limits: [Security and limits](docs/guides/overview.md#security-and-limits).
|
|
@@ -57,7 +57,7 @@ Workers never merge, apply, push to protected branches, write tickets or wiki pa
|
|
|
57
57
|
|
|
58
58
|
## Supported host limitation
|
|
59
59
|
|
|
60
|
-
The current lead-lease implementation supports Linux and macOS process anchors. It fails closed when a session process anchor cannot be established. Windows process-anchor verification (Toolhelp) is not verified; Native Windows is not supported
|
|
60
|
+
The current lead-lease implementation supports Linux and macOS process anchors. It fails closed when a session process anchor cannot be established. Windows process-anchor verification (Toolhelp) is not verified; Native Windows is not supported and is not tested in CI. On Windows, use WSL2.
|
|
61
61
|
|
|
62
62
|
Lead secrets must be presented only by the parent lead CLI, never inherited by a worker. Worker launchers scrub lead material; plugin hooks authenticate host bindings before delivering urgent messages or checking leases. Extensions that perform lead writes must use `with board.lead_write(caller, action):` so validation and mutation share one lock interval.
|
|
63
63
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: raid-worker
|
|
3
|
-
description: Works one raidlock card
|
|
3
|
+
description: Works one raidlock card inside its leased paths, then hands it to review. The prompt must include `card <id>`, the team, agent name and checkout.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, Write, NotebookEdit, Bash
|
|
5
5
|
disallowedTools: Agent
|
|
6
6
|
background: true
|
|
@@ -4,7 +4,7 @@ Images used by the README and guides. All art must be original to raidlock.
|
|
|
4
4
|
|
|
5
5
|
| File | Content | Status |
|
|
6
6
|
|---|---|---|
|
|
7
|
-
| `demo.
|
|
7
|
+
| `demo.webp` | Animated WebP tour of the fictional demo realm (realm tabs, a guild, quest log, quest web, raid frames, treasury, a card, search). 1200 px, 25 fps, about 20 s, recorded at 1440 x 900; shown in the README | generated |
|
|
8
8
|
| `hero.gif`, `hero.mp4` | Terminal recording of [scripts/demo.tape](../../scripts/demo.tape): three quests, two agents claim, an overlapping claim refused, done refused until review and a signed verify receipt, then the measured overhead table. 1200 x 680, 12 fps | generated |
|
|
9
9
|
| `demo-60s.cast` | Terminal recording (asciicast v2) of [scripts/demo-60s.sh](../../scripts/demo-60s.sh): quota routing, auto-handoff to another provider, cross-vendor review, receipt-gated done, cost and reputation per model | generated |
|
|
10
10
|
| `ui-raid-desktop.png`, `ui-plain-desktop.png` | Web board for the demo workspace, full page at 1280 px | generated |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 454.15 83.20" width="227" height="42" role="img" aria-label="raidlock"><title>raidlock</title><g fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 454.15 83.20" width="227" height="42" role="img" aria-label="raidlock"><title>raidlock</title><g fill="#f5c451" transform="scale(1.3)"><circle cx="16" cy="20" r="7"/><circle cx="32" cy="9" r="7"/><circle cx="48" cy="20" r="7"/><path d="M12 20h8v16h-8zM44 20h8v16h-8z"/><path d="M14.3 17.5l15.4-10.6 4.6 5.6-15.4 10.6zM49.7 17.5l-15.4-10.6-4.6 5.6 15.4 10.6z"/><path fill-rule="evenodd" d="M12 32h40a8 8 0 0 1 8 8v16a8 8 0 0 1-8 8H12a8 8 0 0 1-8-8V40a8 8 0 0 1 8-8zM32 40a4 4 0 0 0-4 4v4a4 4 0 0 0 8 0v-4a4 4 0 0 0-4-4z"/></g><path fill="#e6e8ec" transform="translate(99.75 82.20)" d="M5.45 0V-51.56H17.33V-43H17.49Q18.91 -47.44 21.95 -49.75Q24.99 -52.06 30 -52.06Q31.23 -52.06 32.25 -52Q33.27 -51.94 34.01 -51.88V-40.94Q33.33 -41.03 31.67 -41.17Q30.02 -41.31 28.19 -41.31Q25.29 -41.31 22.92 -39.98Q20.55 -38.64 19.17 -35.95Q17.79 -33.27 17.79 -29.21V0Z M54.83 0.83Q49.68 0.83 45.66 -0.89Q41.65 -2.61 39.32 -6.06Q37 -9.51 37 -14.63Q37 -19.04 38.65 -21.9Q40.31 -24.77 43.14 -26.48Q45.98 -28.19 49.64 -29.08Q53.3 -29.97 57.26 -30.39Q62.05 -30.93 64.86 -31.33Q67.66 -31.74 68.87 -32.55Q70.07 -33.37 70.07 -35.13V-35.51Q70.07 -37.73 68.95 -39.42Q67.83 -41.11 65.72 -42.07Q63.61 -43.04 60.65 -43.04Q57.68 -43.04 55.42 -42.08Q53.15 -41.12 51.82 -39.43Q50.49 -37.74 50.3 -35.54H38.46Q38.77 -40.68 41.55 -44.5Q44.32 -48.33 49.25 -50.47Q54.18 -52.61 60.93 -52.61Q65.95 -52.61 69.92 -51.4Q73.89 -50.19 76.65 -47.9Q79.41 -45.62 80.85 -42.4Q82.28 -39.18 82.28 -35.16V0H70.18V-7.29H69.98Q68.77 -4.99 66.83 -3.15Q64.88 -1.3 61.95 -0.24Q59.02 0.83 54.83 0.83ZM57.86 -8.29Q61.87 -8.29 64.61 -9.75Q67.35 -11.22 68.75 -13.65Q70.14 -16.09 70.14 -19.07V-24.68Q69.57 -24.31 68.45 -23.97Q67.33 -23.63 65.79 -23.32Q64.26 -23 62.46 -22.71Q60.67 -22.41 58.77 -22.13Q56.14 -21.76 53.92 -20.9Q51.7 -20.05 50.35 -18.57Q49.01 -17.09 49.01 -14.74Q49.01 -12.74 50.1 -11.28Q51.19 -9.83 53.18 -9.06Q55.17 -8.29 57.86 -8.29Z M92.17 0V-51.56H104.51V0ZM98.32 -59.23Q95.17 -59.23 93.06 -61.25Q90.96 -63.27 90.96 -66.24Q90.96 -69.22 93.06 -71.23Q95.17 -73.23 98.3 -73.23Q101.47 -73.23 103.58 -71.23Q105.69 -69.23 105.69 -66.22Q105.69 -63.25 103.58 -61.24Q101.47 -59.23 98.32 -59.23Z M134.35 1.05Q127.64 1.05 122.61 -2.33Q117.57 -5.71 114.8 -11.75Q112.02 -17.8 112.02 -25.82Q112.02 -33.76 114.82 -39.8Q117.62 -45.84 122.65 -49.22Q127.68 -52.61 134.28 -52.61Q137.65 -52.61 140.55 -51.69Q143.45 -50.78 145.79 -48.93Q148.13 -47.09 149.78 -44.26H149.86V-72.75H162.2V0H150.05V-7.88H149.97Q148.36 -4.89 145.99 -2.9Q143.62 -0.91 140.68 0.07Q137.74 1.05 134.35 1.05ZM137.25 -9.25Q141.28 -9.25 144.27 -11.3Q147.26 -13.35 148.9 -17.08Q150.54 -20.81 150.54 -25.82Q150.54 -30.85 148.9 -34.56Q147.26 -38.28 144.27 -40.33Q141.28 -42.38 137.25 -42.38Q133.46 -42.38 130.58 -40.45Q127.7 -38.53 126.1 -34.84Q124.5 -31.16 124.5 -25.82Q124.5 -20.5 126.1 -16.8Q127.7 -13.1 130.58 -11.18Q133.46 -9.25 137.25 -9.25Z M184.45 -72.75V0H172.1V-72.75Z M217.39 1.17Q209.82 1.17 204.09 -2.22Q198.35 -5.61 195.15 -11.66Q191.96 -17.72 191.96 -25.72Q191.96 -33.75 195.15 -39.83Q198.35 -45.91 204.09 -49.32Q209.82 -52.73 217.39 -52.73Q225.01 -52.73 230.72 -49.32Q236.44 -45.91 239.63 -39.83Q242.83 -33.75 242.83 -25.72Q242.83 -17.72 239.63 -11.66Q236.44 -5.61 230.72 -2.22Q225.01 1.17 217.39 1.17ZM217.39 -9.12Q221.36 -9.12 224.27 -11.13Q227.17 -13.14 228.76 -16.87Q230.35 -20.61 230.35 -25.72Q230.35 -30.91 228.76 -34.63Q227.17 -38.36 224.27 -40.4Q221.36 -42.44 217.39 -42.44Q213.47 -42.44 210.54 -40.42Q207.62 -38.39 206.02 -34.65Q204.43 -30.91 204.43 -25.72Q204.43 -20.58 206.02 -16.86Q207.62 -13.14 210.53 -11.13Q213.44 -9.12 217.39 -9.12Z M273.16 1.17Q265.63 1.17 259.95 -2.24Q254.26 -5.66 251.1 -11.72Q247.94 -17.79 247.94 -25.72Q247.94 -33.68 251.1 -39.78Q254.26 -45.87 259.95 -49.3Q265.63 -52.73 273.16 -52.73Q278.02 -52.73 282.12 -51.29Q286.22 -49.84 289.31 -47.21Q292.39 -44.58 294.27 -41Q296.15 -37.42 296.56 -33.11H284.47Q284.14 -35.2 283.25 -36.91Q282.36 -38.62 280.94 -39.86Q279.52 -41.1 277.61 -41.79Q275.71 -42.47 273.3 -42.47Q269.28 -42.47 266.39 -40.42Q263.49 -38.36 261.95 -34.6Q260.41 -30.84 260.41 -25.72Q260.41 -20.65 261.95 -16.91Q263.49 -13.17 266.38 -11.13Q269.27 -9.09 273.3 -9.09Q275.71 -9.09 277.58 -9.75Q279.46 -10.41 280.81 -11.66Q282.17 -12.9 283.06 -14.64Q283.95 -16.39 284.38 -18.52H296.56Q296.22 -14.27 294.37 -10.68Q292.52 -7.1 289.41 -4.43Q286.3 -1.77 282.17 -0.3Q278.04 1.17 273.16 1.17Z M315.03 -16.09V-30.67H316.25L336.3 -51.56H351.12L327.19 -26.13H324.72ZM303.77 0V-72.75H316.12V0ZM337.67 0 319.8 -23.39 328.08 -32 352.4 0Z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 454.15 83.20" width="227" height="42" role="img" aria-label="raidlock"><title>raidlock</title><g fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 454.15 83.20" width="227" height="42" role="img" aria-label="raidlock"><title>raidlock</title><g fill="#c99a2e" transform="scale(1.3)"><circle cx="16" cy="20" r="7"/><circle cx="32" cy="9" r="7"/><circle cx="48" cy="20" r="7"/><path d="M12 20h8v16h-8zM44 20h8v16h-8z"/><path d="M14.3 17.5l15.4-10.6 4.6 5.6-15.4 10.6zM49.7 17.5l-15.4-10.6-4.6 5.6 15.4 10.6z"/><path fill-rule="evenodd" d="M12 32h40a8 8 0 0 1 8 8v16a8 8 0 0 1-8 8H12a8 8 0 0 1-8-8V40a8 8 0 0 1 8-8zM32 40a4 4 0 0 0-4 4v4a4 4 0 0 0 8 0v-4a4 4 0 0 0-4-4z"/></g><path fill="#1d2129" transform="translate(99.75 82.20)" d="M5.45 0V-51.56H17.33V-43H17.49Q18.91 -47.44 21.95 -49.75Q24.99 -52.06 30 -52.06Q31.23 -52.06 32.25 -52Q33.27 -51.94 34.01 -51.88V-40.94Q33.33 -41.03 31.67 -41.17Q30.02 -41.31 28.19 -41.31Q25.29 -41.31 22.92 -39.98Q20.55 -38.64 19.17 -35.95Q17.79 -33.27 17.79 -29.21V0Z M54.83 0.83Q49.68 0.83 45.66 -0.89Q41.65 -2.61 39.32 -6.06Q37 -9.51 37 -14.63Q37 -19.04 38.65 -21.9Q40.31 -24.77 43.14 -26.48Q45.98 -28.19 49.64 -29.08Q53.3 -29.97 57.26 -30.39Q62.05 -30.93 64.86 -31.33Q67.66 -31.74 68.87 -32.55Q70.07 -33.37 70.07 -35.13V-35.51Q70.07 -37.73 68.95 -39.42Q67.83 -41.11 65.72 -42.07Q63.61 -43.04 60.65 -43.04Q57.68 -43.04 55.42 -42.08Q53.15 -41.12 51.82 -39.43Q50.49 -37.74 50.3 -35.54H38.46Q38.77 -40.68 41.55 -44.5Q44.32 -48.33 49.25 -50.47Q54.18 -52.61 60.93 -52.61Q65.95 -52.61 69.92 -51.4Q73.89 -50.19 76.65 -47.9Q79.41 -45.62 80.85 -42.4Q82.28 -39.18 82.28 -35.16V0H70.18V-7.29H69.98Q68.77 -4.99 66.83 -3.15Q64.88 -1.3 61.95 -0.24Q59.02 0.83 54.83 0.83ZM57.86 -8.29Q61.87 -8.29 64.61 -9.75Q67.35 -11.22 68.75 -13.65Q70.14 -16.09 70.14 -19.07V-24.68Q69.57 -24.31 68.45 -23.97Q67.33 -23.63 65.79 -23.32Q64.26 -23 62.46 -22.71Q60.67 -22.41 58.77 -22.13Q56.14 -21.76 53.92 -20.9Q51.7 -20.05 50.35 -18.57Q49.01 -17.09 49.01 -14.74Q49.01 -12.74 50.1 -11.28Q51.19 -9.83 53.18 -9.06Q55.17 -8.29 57.86 -8.29Z M92.17 0V-51.56H104.51V0ZM98.32 -59.23Q95.17 -59.23 93.06 -61.25Q90.96 -63.27 90.96 -66.24Q90.96 -69.22 93.06 -71.23Q95.17 -73.23 98.3 -73.23Q101.47 -73.23 103.58 -71.23Q105.69 -69.23 105.69 -66.22Q105.69 -63.25 103.58 -61.24Q101.47 -59.23 98.32 -59.23Z M134.35 1.05Q127.64 1.05 122.61 -2.33Q117.57 -5.71 114.8 -11.75Q112.02 -17.8 112.02 -25.82Q112.02 -33.76 114.82 -39.8Q117.62 -45.84 122.65 -49.22Q127.68 -52.61 134.28 -52.61Q137.65 -52.61 140.55 -51.69Q143.45 -50.78 145.79 -48.93Q148.13 -47.09 149.78 -44.26H149.86V-72.75H162.2V0H150.05V-7.88H149.97Q148.36 -4.89 145.99 -2.9Q143.62 -0.91 140.68 0.07Q137.74 1.05 134.35 1.05ZM137.25 -9.25Q141.28 -9.25 144.27 -11.3Q147.26 -13.35 148.9 -17.08Q150.54 -20.81 150.54 -25.82Q150.54 -30.85 148.9 -34.56Q147.26 -38.28 144.27 -40.33Q141.28 -42.38 137.25 -42.38Q133.46 -42.38 130.58 -40.45Q127.7 -38.53 126.1 -34.84Q124.5 -31.16 124.5 -25.82Q124.5 -20.5 126.1 -16.8Q127.7 -13.1 130.58 -11.18Q133.46 -9.25 137.25 -9.25Z M184.45 -72.75V0H172.1V-72.75Z M217.39 1.17Q209.82 1.17 204.09 -2.22Q198.35 -5.61 195.15 -11.66Q191.96 -17.72 191.96 -25.72Q191.96 -33.75 195.15 -39.83Q198.35 -45.91 204.09 -49.32Q209.82 -52.73 217.39 -52.73Q225.01 -52.73 230.72 -49.32Q236.44 -45.91 239.63 -39.83Q242.83 -33.75 242.83 -25.72Q242.83 -17.72 239.63 -11.66Q236.44 -5.61 230.72 -2.22Q225.01 1.17 217.39 1.17ZM217.39 -9.12Q221.36 -9.12 224.27 -11.13Q227.17 -13.14 228.76 -16.87Q230.35 -20.61 230.35 -25.72Q230.35 -30.91 228.76 -34.63Q227.17 -38.36 224.27 -40.4Q221.36 -42.44 217.39 -42.44Q213.47 -42.44 210.54 -40.42Q207.62 -38.39 206.02 -34.65Q204.43 -30.91 204.43 -25.72Q204.43 -20.58 206.02 -16.86Q207.62 -13.14 210.53 -11.13Q213.44 -9.12 217.39 -9.12Z M273.16 1.17Q265.63 1.17 259.95 -2.24Q254.26 -5.66 251.1 -11.72Q247.94 -17.79 247.94 -25.72Q247.94 -33.68 251.1 -39.78Q254.26 -45.87 259.95 -49.3Q265.63 -52.73 273.16 -52.73Q278.02 -52.73 282.12 -51.29Q286.22 -49.84 289.31 -47.21Q292.39 -44.58 294.27 -41Q296.15 -37.42 296.56 -33.11H284.47Q284.14 -35.2 283.25 -36.91Q282.36 -38.62 280.94 -39.86Q279.52 -41.1 277.61 -41.79Q275.71 -42.47 273.3 -42.47Q269.28 -42.47 266.39 -40.42Q263.49 -38.36 261.95 -34.6Q260.41 -30.84 260.41 -25.72Q260.41 -20.65 261.95 -16.91Q263.49 -13.17 266.38 -11.13Q269.27 -9.09 273.3 -9.09Q275.71 -9.09 277.58 -9.75Q279.46 -10.41 280.81 -11.66Q282.17 -12.9 283.06 -14.64Q283.95 -16.39 284.38 -18.52H296.56Q296.22 -14.27 294.37 -10.68Q292.52 -7.1 289.41 -4.43Q286.3 -1.77 282.17 -0.3Q278.04 1.17 273.16 1.17Z M315.03 -16.09V-30.67H316.25L336.3 -51.56H351.12L327.19 -26.13H324.72ZM303.77 0V-72.75H316.12V0ZM337.67 0 319.8 -23.39 328.08 -32 352.4 0Z"/></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="raidlock"><title>raidlock</title><g fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="raidlock"><title>raidlock</title><g fill="#f5c451"><circle cx="16" cy="20" r="7"/><circle cx="32" cy="9" r="7"/><circle cx="48" cy="20" r="7"/><path d="M12 20h8v16h-8zM44 20h8v16h-8z"/><path d="M14.3 17.5l15.4-10.6 4.6 5.6-15.4 10.6zM49.7 17.5l-15.4-10.6-4.6 5.6 15.4 10.6z"/><path fill-rule="evenodd" d="M12 32h40a8 8 0 0 1 8 8v16a8 8 0 0 1-8 8H12a8 8 0 0 1-8-8V40a8 8 0 0 1 8-8zM32 40a4 4 0 0 0-4 4v4a4 4 0 0 0 8 0v-4a4 4 0 0 0-4-4z"/></g></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="raidlock"><title>raidlock</title><g fill="#
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="raidlock"><title>raidlock</title><g fill="#c99a2e"><circle cx="16" cy="20" r="7"/><circle cx="32" cy="9" r="7"/><circle cx="48" cy="20" r="7"/><path d="M12 20h8v16h-8zM44 20h8v16h-8z"/><path d="M14.3 17.5l15.4-10.6 4.6 5.6-15.4 10.6zM49.7 17.5l-15.4-10.6-4.6 5.6 15.4 10.6z"/><path fill-rule="evenodd" d="M12 32h40a8 8 0 0 1 8 8v16a8 8 0 0 1-8 8H12a8 8 0 0 1-8-8V40a8 8 0 0 1 8-8zM32 40a4 4 0 0 0-4 4v4a4 4 0 0 0 8 0v-4a4 4 0 0 0-4-4z"/></g></svg>
|
|
Binary file
|