@soleur/opencode 0.0.0-stage → 1.0.0
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.
- package/.claude-plugin/agents.manifest.json +476 -0
- package/.claude-plugin/plugin.json +42 -0
- package/README.md +44 -2
- package/agents/community/.gitkeep +0 -0
- package/agents/engineering/cto.md +87 -0
- package/agents/engineering/design/ddd-architect.md +95 -0
- package/agents/engineering/discovery/agent-finder.md +214 -0
- package/agents/engineering/discovery/functional-discovery.md +182 -0
- package/agents/engineering/infra/infra-security.md +151 -0
- package/agents/engineering/infra/platform-strategist.md +109 -0
- package/agents/engineering/infra/terraform-architect.md +171 -0
- package/agents/engineering/prompt-engineer.md +37 -0
- package/agents/engineering/research/best-practices-researcher.md +115 -0
- package/agents/engineering/research/framework-docs-researcher.md +93 -0
- package/agents/engineering/research/git-history-analyzer.md +53 -0
- package/agents/engineering/research/learnings-researcher.md +285 -0
- package/agents/engineering/research/repo-research-analyst.md +118 -0
- package/agents/engineering/review/agent-native-reviewer.md +279 -0
- package/agents/engineering/review/architecture-strategist.md +61 -0
- package/agents/engineering/review/code-quality-analyst.md +92 -0
- package/agents/engineering/review/code-simplicity-reviewer.md +109 -0
- package/agents/engineering/review/data-integrity-guardian.md +82 -0
- package/agents/engineering/review/data-migration-expert.md +98 -0
- package/agents/engineering/review/deployment-verification-agent.md +183 -0
- package/agents/engineering/review/dhh-rails-reviewer.md +46 -0
- package/agents/engineering/review/kieran-rails-reviewer.md +87 -0
- package/agents/engineering/review/legacy-code-expert.md +55 -0
- package/agents/engineering/review/observability-coverage-reviewer.md +147 -0
- package/agents/engineering/review/pattern-recognition-specialist.md +59 -0
- package/agents/engineering/review/performance-oracle.md +130 -0
- package/agents/engineering/review/security-sentinel.md +167 -0
- package/agents/engineering/review/semgrep-sast.md +36 -0
- package/agents/engineering/review/test-design-reviewer.md +150 -0
- package/agents/engineering/review/user-impact-reviewer.md +70 -0
- package/agents/engineering/workflow/pr-comment-resolver.md +69 -0
- package/agents/finance/budget-analyst.md +29 -0
- package/agents/finance/cfo.md +44 -0
- package/agents/finance/financial-reporter.md +30 -0
- package/agents/finance/revenue-analyst.md +30 -0
- package/agents/legal/clo.md +115 -0
- package/agents/legal/legal-compliance-auditor.md +110 -0
- package/agents/legal/legal-document-generator.md +134 -0
- package/agents/marketing/analytics-analyst.md +25 -0
- package/agents/marketing/brand-architect.md +181 -0
- package/agents/marketing/cmo.md +76 -0
- package/agents/marketing/conversion-optimizer.md +19 -0
- package/agents/marketing/copywriter.md +20 -0
- package/agents/marketing/fact-checker.md +70 -0
- package/agents/marketing/growth-strategist.md +145 -0
- package/agents/marketing/paid-media-strategist.md +28 -0
- package/agents/marketing/pricing-strategist.md +17 -0
- package/agents/marketing/programmatic-seo-specialist.md +25 -0
- package/agents/marketing/retention-strategist.md +23 -0
- package/agents/marketing/seo-aeo-analyst.md +164 -0
- package/agents/operations/coo.md +50 -0
- package/agents/operations/ops-advisor.md +78 -0
- package/agents/operations/ops-provisioner.md +101 -0
- package/agents/operations/ops-research.md +52 -0
- package/agents/operations/service-automator.md +278 -0
- package/agents/product/business-validator.md +206 -0
- package/agents/product/competitive-intelligence.md +89 -0
- package/agents/product/cpo.md +63 -0
- package/agents/product/design/ux-design-lead.md +209 -0
- package/agents/product/spec-flow-analyzer.md +122 -0
- package/agents/sales/cro.md +44 -0
- package/agents/sales/deal-architect.md +29 -0
- package/agents/sales/outbound-strategist.md +29 -0
- package/agents/sales/pipeline-analyst.md +29 -0
- package/agents/support/cco.md +48 -0
- package/agents/support/community-manager.md +570 -0
- package/agents/support/ticket-triage.md +70 -0
- package/bin/soleur-opencode.js +29 -0
- package/commands/go.md +659 -0
- package/commands/help.md +273 -0
- package/commands/sync.md +977 -0
- package/commands/version.md +103 -0
- package/hooks/antigravity-hooks.json +84 -0
- package/hooks/antigravity-session-start.sh +15 -0
- package/hooks/bare-root-cwd-guard.sh +131 -0
- package/hooks/browser-snapshot-credential-guard.sh +200 -0
- package/hooks/codex-session-start.sh +9 -0
- package/hooks/compaction-state.sh +525 -0
- package/hooks/destructive-command-guard.sh +1387 -0
- package/hooks/devin-session-start.sh +90 -0
- package/hooks/ext-filter-detect.sh +171 -0
- package/hooks/hooks.json +133 -0
- package/hooks/lib/hook-tool-kind.sh +24 -0
- package/hooks/lib/log-rotation.sh +176 -0
- package/hooks/lib/shell-argv.pl +576 -0
- package/hooks/memory-backstop.sh +1114 -0
- package/hooks/operator-stage-approval.sh +391 -0
- package/hooks/stop-hook.sh +367 -0
- package/hooks/unkept-promise-hook.sh +383 -0
- package/hooks/version-banner.sh +127 -0
- package/hooks/welcome-hook.sh +50 -0
- package/install.js +108 -0
- package/lib/agent-registry.ts +154 -0
- package/lib/c4-canonical-cli.mjs +34 -0
- package/lib/c4-canonical.mjs +46 -0
- package/lib/c4-from-components.ts +554 -0
- package/lib/go-routing.ts +81 -0
- package/lib/grok-inspect-contract.ts +311 -0
- package/lib/harness-model-map.ts +101 -0
- package/lib/harness-parity.ts +726 -0
- package/lib/harness-tool-map.ts +180 -0
- package/lib/harness.ts +716 -0
- package/lib/heartbeat-live-reconcile.ts +1153 -0
- package/lib/heartbeat-manifest.ts +342 -0
- package/lib/kb-coverage.ts +252 -0
- package/lib/pr-merge-poll.ts +103 -0
- package/lib/workflow-fidelity.ts +388 -0
- package/opencode/INSTRUCTIONS.md +152 -0
- package/opencode/agents/engineering/cto.md +10 -0
- package/opencode/agents/engineering/design/ddd-architect.md +10 -0
- package/opencode/agents/engineering/discovery/agent-finder.md +10 -0
- package/opencode/agents/engineering/discovery/functional-discovery.md +10 -0
- package/opencode/agents/engineering/infra/infra-security.md +10 -0
- package/opencode/agents/engineering/infra/platform-strategist.md +10 -0
- package/opencode/agents/engineering/infra/terraform-architect.md +10 -0
- package/opencode/agents/engineering/prompt-engineer.md +10 -0
- package/opencode/agents/engineering/research/best-practices-researcher.md +10 -0
- package/opencode/agents/engineering/research/framework-docs-researcher.md +10 -0
- package/opencode/agents/engineering/research/git-history-analyzer.md +10 -0
- package/opencode/agents/engineering/research/learnings-researcher.md +10 -0
- package/opencode/agents/engineering/research/repo-research-analyst.md +10 -0
- package/opencode/agents/engineering/review/agent-native-reviewer.md +10 -0
- package/opencode/agents/engineering/review/architecture-strategist.md +10 -0
- package/opencode/agents/engineering/review/code-quality-analyst.md +10 -0
- package/opencode/agents/engineering/review/code-simplicity-reviewer.md +10 -0
- package/opencode/agents/engineering/review/data-integrity-guardian.md +10 -0
- package/opencode/agents/engineering/review/data-migration-expert.md +10 -0
- package/opencode/agents/engineering/review/deployment-verification-agent.md +10 -0
- package/opencode/agents/engineering/review/dhh-rails-reviewer.md +10 -0
- package/opencode/agents/engineering/review/kieran-rails-reviewer.md +10 -0
- package/opencode/agents/engineering/review/legacy-code-expert.md +10 -0
- package/opencode/agents/engineering/review/observability-coverage-reviewer.md +10 -0
- package/opencode/agents/engineering/review/pattern-recognition-specialist.md +10 -0
- package/opencode/agents/engineering/review/performance-oracle.md +10 -0
- package/opencode/agents/engineering/review/security-sentinel.md +10 -0
- package/opencode/agents/engineering/review/semgrep-sast.md +10 -0
- package/opencode/agents/engineering/review/test-design-reviewer.md +10 -0
- package/opencode/agents/engineering/review/user-impact-reviewer.md +10 -0
- package/opencode/agents/engineering/workflow/pr-comment-resolver.md +10 -0
- package/opencode/agents/finance/budget-analyst.md +10 -0
- package/opencode/agents/finance/cfo.md +10 -0
- package/opencode/agents/finance/financial-reporter.md +10 -0
- package/opencode/agents/finance/revenue-analyst.md +10 -0
- package/opencode/agents/legal/clo.md +10 -0
- package/opencode/agents/legal/legal-compliance-auditor.md +10 -0
- package/opencode/agents/legal/legal-document-generator.md +10 -0
- package/opencode/agents/marketing/analytics-analyst.md +10 -0
- package/opencode/agents/marketing/brand-architect.md +10 -0
- package/opencode/agents/marketing/cmo.md +10 -0
- package/opencode/agents/marketing/conversion-optimizer.md +10 -0
- package/opencode/agents/marketing/copywriter.md +10 -0
- package/opencode/agents/marketing/fact-checker.md +10 -0
- package/opencode/agents/marketing/growth-strategist.md +10 -0
- package/opencode/agents/marketing/paid-media-strategist.md +10 -0
- package/opencode/agents/marketing/pricing-strategist.md +10 -0
- package/opencode/agents/marketing/programmatic-seo-specialist.md +10 -0
- package/opencode/agents/marketing/retention-strategist.md +10 -0
- package/opencode/agents/marketing/seo-aeo-analyst.md +10 -0
- package/opencode/agents/operations/coo.md +10 -0
- package/opencode/agents/operations/ops-advisor.md +10 -0
- package/opencode/agents/operations/ops-provisioner.md +10 -0
- package/opencode/agents/operations/ops-research.md +10 -0
- package/opencode/agents/operations/service-automator.md +10 -0
- package/opencode/agents/product/business-validator.md +10 -0
- package/opencode/agents/product/competitive-intelligence.md +10 -0
- package/opencode/agents/product/cpo.md +10 -0
- package/opencode/agents/product/design/ux-design-lead.md +10 -0
- package/opencode/agents/product/spec-flow-analyzer.md +10 -0
- package/opencode/agents/sales/cro.md +10 -0
- package/opencode/agents/sales/deal-architect.md +10 -0
- package/opencode/agents/sales/outbound-strategist.md +10 -0
- package/opencode/agents/sales/pipeline-analyst.md +10 -0
- package/opencode/agents/support/cco.md +10 -0
- package/opencode/agents/support/community-manager.md +10 -0
- package/opencode/agents/support/ticket-triage.md +10 -0
- package/opencode/commands/go.md +10 -0
- package/opencode/commands/help.md +10 -0
- package/opencode/commands/sync.md +10 -0
- package/opencode/commands/version.md +11 -0
- package/opencode/opencode.json +8 -0
- package/opencode/plugin.ts +493 -0
- package/package.json +36 -4
- package/scripts/admin-merge-ready.sh +545 -0
- package/scripts/admin-merge-ready.test.sh +753 -0
- package/scripts/affected-tests.sh +908 -0
- package/scripts/affected-tests.test.sh +1797 -0
- package/scripts/alpha-metrics.sh +78 -0
- package/scripts/alpha-metrics.test.sh +115 -0
- package/scripts/ancestor-signal-helpers.baseline.txt +16 -0
- package/scripts/audit-flag-flip.sh +107 -0
- package/scripts/check-red-on-main.sh +316 -0
- package/scripts/ci-head-verdict.sh +363 -0
- package/scripts/cloud-detect.sh +193 -0
- package/scripts/delegation-verify.sh +657 -0
- package/scripts/delegation-verify.test.sh +1424 -0
- package/scripts/deploy-arm.sh +475 -0
- package/scripts/domain-model-drift.sh +419 -0
- package/scripts/emit-decision.sh +144 -0
- package/scripts/emit-decision.test.sh +144 -0
- package/scripts/ext-filter-divergence-corpus.txt +15 -0
- package/scripts/ext-filter-divergence.sh +189 -0
- package/scripts/generate-c4-from-components.ts +442 -0
- package/scripts/grok-fidelity-gate.sh +68 -0
- package/scripts/grok-pre-push-gate.sh +232 -0
- package/scripts/harness-discovery-smoke.ts +906 -0
- package/scripts/harness-parity-census.ts +92 -0
- package/scripts/inngest-luks-alert-armed-probe.ts +29 -0
- package/scripts/install-opencode-adapter.ts +520 -0
- package/scripts/lib/affected-tests/common.sh +365 -0
- package/scripts/lib/affected-tests/go.sh +157 -0
- package/scripts/lib/affected-tests/js.sh +188 -0
- package/scripts/lib/affected-tests/nx-turbo.sh +98 -0
- package/scripts/lib/affected-tests/python.sh +185 -0
- package/scripts/lib/context-sanitize.sh +49 -0
- package/scripts/lib/domain-model-lib.sh +180 -0
- package/scripts/lib/ext-filter-grammar.tsv +34 -0
- package/scripts/lib/operator-script.sh +1236 -0
- package/scripts/lib/proc.sh +580 -0
- package/scripts/lib/session-state.sh +748 -0
- package/scripts/lib/tmp-classify.sh +843 -0
- package/scripts/lib/wrapper-boundary.sh +47 -0
- package/scripts/lint-ratchet.py +1547 -0
- package/scripts/monitor-pr-checks.sh +441 -0
- package/scripts/pipeline-tally.sh +756 -0
- package/scripts/pipeline-tally.test.sh +740 -0
- package/scripts/plugin-version.sh +528 -0
- package/scripts/precommit-guard.sh +113 -0
- package/scripts/precommit-guard.test.sh +254 -0
- package/scripts/reconcile-live-heartbeats.ts +705 -0
- package/scripts/render-c4-model.sh +217 -0
- package/scripts/resolve-git-root.sh +55 -0
- package/scripts/resolve-regenerable-conflicts.sh +363 -0
- package/scripts/resolve-regenerable-conflicts.test.sh +780 -0
- package/scripts/ruff-requirements.txt +22 -0
- package/scripts/run-in-pid-namespace.sh +98 -0
- package/scripts/run-in-pid-namespace.test.sh +290 -0
- package/scripts/scan-ancestor-signal-helpers.py +556 -0
- package/scripts/scan-ancestor-signal-helpers.test.sh +670 -0
- package/scripts/setup-ralph-loop.sh +238 -0
- package/scripts/sync-cursor-name-map.ts +316 -0
- package/scripts/sync-grok-agent-compat.ts +188 -0
- package/scripts/sync-npm-package.ts +178 -0
- package/scripts/sync-opencode-adapter.ts +479 -0
- package/scripts/sync-pr-behind.sh +534 -0
- package/scripts/sync-pr-behind.test.sh +252 -0
- package/scripts/taste-profile-update.sh +180 -0
- package/scripts/taste-profile-update.test.sh +167 -0
- package/scripts/write-budget-marker.sh +23 -0
- package/scripts/write-kb-coverage.ts +113 -0
- package/skills/admin-ip-refresh/SKILL.md +81 -0
- package/skills/admin-ip-refresh/references/admin-ip-refresh-procedure.md +201 -0
- package/skills/agent-browser/SKILL.md +698 -0
- package/skills/agent-browser/scripts/playwright-mcp-profile-slot.sh +304 -0
- package/skills/agent-browser/scripts/playwright-mcp-redact-proxy.py +964 -0
- package/skills/agent-browser/scripts/redact-a11y-snapshot.py +443 -0
- package/skills/agent-browser/test/fixtures/capture-playwright-mcp-fixtures.py +217 -0
- package/skills/agent-browser/test/fixtures/fake-passthrough-proxy.py +24 -0
- package/skills/agent-browser/test/fixtures/fake-playwright-mcp.py +131 -0
- package/skills/agent-browser/test/fixtures/make-proxy-mutant.py +48 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/dialog-link-injection.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/empty-content.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-and-result.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-code-bool.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-code-string.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-message-tree.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-no-data.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-string.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/error-with-data.json +9 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/evaluate-escaped-object.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/invalid-utf8.json +4 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/link-result.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/list-two-results.json +6 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/meta-in-result.json +13 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/no-content.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/quoted-key.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/resource-block.json +18 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/result-and-method.json +11 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/result-string.json +3 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped-one-row.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/run-code-escaped.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/structured-content.json +13 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/tools-list-no-tools.json +5 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/tree-no-credential.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/two-text-blocks.json +14 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/unparsable-line.json +3 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-brace.json +10 -0
- package/skills/agent-browser/test/fixtures/odd-shapes/value-contains-link-substring.json +10 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/close.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/evaluate.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/find.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/framing.json +6 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/initialize.json +14 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate-link.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/navigate.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/roots-list-request.json +5 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/screenshot.json +17 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-filename.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-json.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot-meta-raw.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/snapshot.json +12 -0
- package/skills/agent-browser/test/fixtures/playwright-mcp-0.0.78/tools-list.json +827 -0
- package/skills/agent-browser/test/fixtures/proxy-session-driver.py +138 -0
- package/skills/agent-browser/test/fixtures/session-facts.py +102 -0
- package/skills/agent-browser/test/playwright-mcp-lifetime.test.sh +1620 -0
- package/skills/agent-browser/test/playwright-mcp-redact-proxy.test.sh +1599 -0
- package/skills/agent-browser/test/redact-a11y-snapshot.test.sh +527 -0
- package/skills/agent-native-architecture/SKILL.md +479 -0
- package/skills/agent-native-architecture/references/action-parity-discipline.md +430 -0
- package/skills/agent-native-architecture/references/agent-execution-patterns.md +483 -0
- package/skills/agent-native-architecture/references/agent-native-testing.md +605 -0
- package/skills/agent-native-architecture/references/architecture-patterns.md +493 -0
- package/skills/agent-native-architecture/references/dynamic-context-injection.md +358 -0
- package/skills/agent-native-architecture/references/files-universal-interface.md +314 -0
- package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +381 -0
- package/skills/agent-native-architecture/references/mcp-tool-design.md +524 -0
- package/skills/agent-native-architecture/references/mobile-patterns.md +897 -0
- package/skills/agent-native-architecture/references/product-implications.md +478 -0
- package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +342 -0
- package/skills/agent-native-architecture/references/self-modification.md +294 -0
- package/skills/agent-native-architecture/references/shared-workspace-architecture.md +700 -0
- package/skills/agent-native-architecture/references/system-prompt-design.md +263 -0
- package/skills/agent-native-audit/SKILL.md +300 -0
- package/skills/agent-native-audit/workflows/agent-native-audit.workflow.js +423 -0
- package/skills/andrew-kane-gem-writer/SKILL.md +189 -0
- package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
- package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
- package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
- package/skills/andrew-kane-gem-writer/references/resources.md +126 -0
- package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
- package/skills/architecture/SKILL.md +436 -0
- package/skills/architecture/references/adr-template.md +154 -0
- package/skills/architecture/references/likec4-reference.md +136 -0
- package/skills/architecture/references/nfr-reference.md +126 -0
- package/skills/archive-kb/SKILL.md +86 -0
- package/skills/archive-kb/scripts/archive-kb.sh +300 -0
- package/skills/archive-kb/test/archive-kb-partial-run.test.sh +276 -0
- package/skills/atdd-developer/SKILL.md +65 -0
- package/skills/brainstorm/SKILL.md +701 -0
- package/skills/brainstorm/references/brainstorm-brand-workshop.md +153 -0
- package/skills/brainstorm/references/brainstorm-domain-config.md +63 -0
- package/skills/brainstorm/references/brainstorm-validation-workshop.md +65 -0
- package/skills/brainstorm/references/ui-surface-terms.md +42 -0
- package/skills/brainstorm-techniques/SKILL.md +231 -0
- package/skills/brainstorm-techniques/references/decision-principles.md +150 -0
- package/skills/brainstorm-techniques/references/phase-boundaries.md +103 -0
- package/skills/brainstorm-techniques/references/standing-delegation.md +407 -0
- package/skills/brainstorm-techniques/references/technical-ruling-delegation.md +174 -0
- package/skills/campaign-calendar/SKILL.md +145 -0
- package/skills/cf-token-scope/SKILL.md +164 -0
- package/skills/cf-token-scope/references/widen-playbook.md +114 -0
- package/skills/cf-token-scope/scripts/cf-token-scope.sh +253 -0
- package/skills/changelog/SKILL.md +142 -0
- package/skills/code-to-prd/SKILL.md +66 -0
- package/skills/code-to-prd/references/banner-template.md +12 -0
- package/skills/code-to-prd/references/prd-template.md +41 -0
- package/skills/code-to-prd/scripts/code-to-prd.sh +634 -0
- package/skills/code-to-prd/test/code-to-prd.test.sh +447 -0
- package/skills/code-to-prd/test/fixture/.env.example +7 -0
- package/skills/code-to-prd/test/fixture/app/about/page.tsx +11 -0
- package/skills/code-to-prd/test/fixture/app/api/health/route.ts +10 -0
- package/skills/code-to-prd/test/fixture/app/page.tsx +14 -0
- package/skills/code-to-prd/test/fixture/next.config.mjs +3 -0
- package/skills/code-to-prd/test/fixture/package.json +6 -0
- package/skills/cohort-status/SKILL.md +62 -0
- package/skills/community/SKILL.md +210 -0
- package/skills/community/scripts/bsky-community.sh +644 -0
- package/skills/community/scripts/bsky-setup.sh +631 -0
- package/skills/community/scripts/community-router.sh +93 -0
- package/skills/community/scripts/discord-community.sh +487 -0
- package/skills/community/scripts/discord-setup.sh +784 -0
- package/skills/community/scripts/github-community.sh +706 -0
- package/skills/community/scripts/hn-community.sh +233 -0
- package/skills/community/scripts/lib/hmac-sha1-b64.sh +126 -0
- package/skills/community/scripts/linkedin-community.sh +750 -0
- package/skills/community/scripts/linkedin-setup.sh +758 -0
- package/skills/community/scripts/x-community.sh +890 -0
- package/skills/community/scripts/x-setup.sh +713 -0
- package/skills/community/test/community-argv.test.sh +2922 -0
- package/skills/community/test/github-community.test.sh +981 -0
- package/skills/competitive-analysis/SKILL.md +69 -0
- package/skills/competitive-analysis/references/peer-plugin-audit.md +218 -0
- package/skills/compound/SKILL.md +673 -0
- package/skills/compound/scripts/token-efficiency-report.sh +334 -0
- package/skills/compound/test/phase-16.test.sh +379 -0
- package/skills/compound-capture/SKILL.md +791 -0
- package/skills/compound-capture/assets/critical-pattern-template.md +37 -0
- package/skills/compound-capture/assets/resolution-template.md +116 -0
- package/skills/compound-capture/references/yaml-schema.md +67 -0
- package/skills/compound-capture/schema.yaml +181 -0
- package/skills/constraint-scaffold/SKILL.md +175 -0
- package/skills/constraint-scaffold/references/boundary-readme.template +35 -0
- package/skills/constraint-scaffold/references/constraint-gates-workflow.template +69 -0
- package/skills/constraint-scaffold/references/depcruise-config.template +230 -0
- package/skills/constraint-scaffold/references/fix-constraints-stage-a.template +240 -0
- package/skills/constraint-scaffold/references/fix-constraints-stage-b.template +313 -0
- package/skills/constraint-scaffold/references/shared-runner.template +135 -0
- package/skills/constraint-scaffold/scripts/constraint-scaffold.sh +589 -0
- package/skills/constraint-scaffold/test/bite-proof.test.sh +1338 -0
- package/skills/constraint-scaffold/test/boundary.test.sh +734 -0
- package/skills/constraint-scaffold/test/emit-fix-constraints.test.sh +193 -0
- package/skills/constraint-scaffold/test/generator.test.sh +93 -0
- package/skills/constraint-scaffold/test/parity.test.sh +285 -0
- package/skills/content-writer/SKILL.md +242 -0
- package/skills/content-writer/scripts/blog-jargon-scan.sh +42 -0
- package/skills/cron-delete/SKILL.md +56 -0
- package/skills/cron-list/SKILL.md +54 -0
- package/skills/deepen-plan/SKILL.md +937 -0
- package/skills/deepen-plan/workflows/deepen-plan.workflow.js +488 -0
- package/skills/deploy/SKILL.md +115 -0
- package/skills/deploy/references/hetzner-setup.md +65 -0
- package/skills/deploy/scripts/deploy.sh +37 -0
- package/skills/deploy-docs/SKILL.md +95 -0
- package/skills/dhh-rails-style/SKILL.md +203 -0
- package/skills/dhh-rails-style/references/architecture.md +717 -0
- package/skills/dhh-rails-style/references/controllers.md +323 -0
- package/skills/dhh-rails-style/references/frontend.md +556 -0
- package/skills/dhh-rails-style/references/gems.md +316 -0
- package/skills/dhh-rails-style/references/models.md +388 -0
- package/skills/dhh-rails-style/references/testing.md +354 -0
- package/skills/discord-content/SKILL.md +126 -0
- package/skills/docs-site/SKILL.md +214 -0
- package/skills/drain-labeled-backlog/SKILL.md +203 -0
- package/skills/drain-labeled-backlog/scripts/group-by-area.sh +208 -0
- package/skills/drain-labeled-backlog/workflows/drain-labeled-backlog.workflow.js +433 -0
- package/skills/drain-prs/SKILL.md +142 -0
- package/skills/drain-prs/scripts/triage-prs.sh +192 -0
- package/skills/drain-prs/test/argv-ceiling.test.sh +183 -0
- package/skills/dspy-ruby/SKILL.md +634 -0
- package/skills/dspy-ruby/assets/config-template.rb +359 -0
- package/skills/dspy-ruby/assets/module-template.rb +326 -0
- package/skills/dspy-ruby/assets/signature-template.rb +143 -0
- package/skills/dspy-ruby/references/core-concepts.md +268 -0
- package/skills/dspy-ruby/references/optimization.md +623 -0
- package/skills/dspy-ruby/references/providers.md +335 -0
- package/skills/eval-harness/README.md +194 -0
- package/skills/eval-harness/SKILL.md +157 -0
- package/skills/eval-harness/enums/go-routes.json +13 -0
- package/skills/eval-harness/enums/incident-threshold.json +5 -0
- package/skills/eval-harness/enums/lane.json +5 -0
- package/skills/eval-harness/enums/tool-selection.json +20 -0
- package/skills/eval-harness/enums/triage-levels.json +5 -0
- package/skills/eval-harness/gated-skills.json +34 -0
- package/skills/eval-harness/models.generated.json +5 -0
- package/skills/eval-harness/promptfooconfig-go-routing.yaml +35 -0
- package/skills/eval-harness/promptfooconfig-incident-threshold.yaml +32 -0
- package/skills/eval-harness/promptfooconfig-lane-inference.yaml +33 -0
- package/skills/eval-harness/promptfooconfig-ticket-triage.yaml +34 -0
- package/skills/eval-harness/promptfooconfig-tool-selection.yaml +33 -0
- package/skills/eval-harness/prompts/go-baseline.txt +6 -0
- package/skills/eval-harness/prompts/go-skill.txt +21 -0
- package/skills/eval-harness/prompts/incident-threshold-baseline.txt +6 -0
- package/skills/eval-harness/prompts/incident-threshold-skill.txt +12 -0
- package/skills/eval-harness/prompts/lane-inference-baseline.txt +6 -0
- package/skills/eval-harness/prompts/lane-inference-skill.txt +15 -0
- package/skills/eval-harness/prompts/tool-selection-baseline.txt +19 -0
- package/skills/eval-harness/prompts/tool-selection-skill.txt +22 -0
- package/skills/eval-harness/prompts/triage-baseline.txt +7 -0
- package/skills/eval-harness/prompts/triage-skill.txt +10 -0
- package/skills/eval-harness/scripts/eval-gate.cjs +318 -0
- package/skills/eval-harness/scripts/extract-block.cjs +87 -0
- package/skills/eval-harness/scripts/gate-classification.cjs +28 -0
- package/skills/eval-harness/scripts/gen-models.sh +41 -0
- package/skills/eval-harness/scripts/gen-skill-prompt.cjs +177 -0
- package/skills/eval-harness/scripts/measure-classification.cjs +30 -0
- package/skills/eval-harness/scripts/parse-label.cjs +93 -0
- package/skills/eval-harness/scripts/verdict.cjs +132 -0
- package/skills/eval-harness/tasks/go-routing.jsonl +8 -0
- package/skills/eval-harness/tasks/incident-threshold.jsonl +7 -0
- package/skills/eval-harness/tasks/lane-inference.jsonl +7 -0
- package/skills/eval-harness/tasks/ticket-triage.jsonl +6 -0
- package/skills/eval-harness/tasks/tool-selection.jsonl +15 -0
- package/skills/eval-harness/test/eval-gate.test.sh +132 -0
- package/skills/eval-harness/test/extract-block.test.sh +87 -0
- package/skills/eval-harness/test/gate-classification.test.sh +77 -0
- package/skills/eval-harness/test/gen-models.test.sh +75 -0
- package/skills/eval-harness/test/measure-classification.test.sh +74 -0
- package/skills/eval-harness/test/parse-label.test.sh +129 -0
- package/skills/eval-harness/test/registry-completeness.test.sh +109 -0
- package/skills/eval-harness/test/verdict.test.sh +123 -0
- package/skills/every-style-editor/SKILL.md +142 -0
- package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
- package/skills/feature-tweet/SKILL.md +199 -0
- package/skills/feature-video/SKILL.md +412 -0
- package/skills/feature-video/scripts/check_deps.sh +281 -0
- package/skills/file-todos/SKILL.md +267 -0
- package/skills/file-todos/assets/todo-template.md +166 -0
- package/skills/fix-issue/SKILL.md +278 -0
- package/skills/fix-issue/references/agent-authored-exclusion.md +118 -0
- package/skills/fix-issue/references/exclude-label-jq-snippet.md +96 -0
- package/skills/flag-bootstrap/SETUP.md +142 -0
- package/skills/flag-create/SKILL.md +145 -0
- package/skills/flag-create/scripts/create.sh +273 -0
- package/skills/flag-delete/SKILL.md +167 -0
- package/skills/flag-delete/scripts/delete.sh +288 -0
- package/skills/flag-list/SKILL.md +99 -0
- package/skills/flag-list/scripts/list.sh +275 -0
- package/skills/flag-set-role/SKILL.md +229 -0
- package/skills/flag-set-role/scripts/flip.sh +774 -0
- package/skills/frontend-anti-slop/SKILL.md +106 -0
- package/skills/frontend-anti-slop/references/anti-patterns.md +199 -0
- package/skills/frontend-anti-slop/references/slop-rules.md +65 -0
- package/skills/frontend-anti-slop/scripts/tier1-scan.ts +525 -0
- package/skills/frontend-design/SKILL.md +77 -0
- package/skills/gdpr-gate/NOTICE +136 -0
- package/skills/gdpr-gate/SKILL.md +341 -0
- package/skills/gdpr-gate/references/fields.md +160 -0
- package/skills/gdpr-gate/references/layers/api-layer.md +355 -0
- package/skills/gdpr-gate/references/layers/auth-sessions.md +290 -0
- package/skills/gdpr-gate/references/layers/data-in-transit.md +331 -0
- package/skills/gdpr-gate/references/layers/data-lifecycle.md +341 -0
- package/skills/gdpr-gate/references/layers/frontend.md +249 -0
- package/skills/gdpr-gate/references/layers/testing-seeding.md +256 -0
- package/skills/gdpr-gate/references/leakage-vectors.md +248 -0
- package/skills/gdpr-gate/references/legacy/legal-consent-v1-prose.md +48 -0
- package/skills/gdpr-gate/references/legal-consent.md +140 -0
- package/skills/gdpr-gate/references/non-negotiables.md +60 -0
- package/skills/gdpr-gate/scripts/gdpr-gate.sh +271 -0
- package/skills/gdpr-gate/scripts/notice-frontmatter.sh +337 -0
- package/skills/gdpr-gate/scripts/path-denylist.txt +39 -0
- package/skills/gdpr-gate/scripts/repo-scan.sh +158 -0
- package/skills/gdpr-gate/scripts/vendor-drift-classify.sh +120 -0
- package/skills/gdpr-gate/scripts/vendor-pin-integrity.sh +237 -0
- package/skills/gemini-imagegen/SKILL.md +283 -0
- package/skills/gemini-imagegen/requirements.txt +5 -0
- package/skills/gemini-imagegen/scripts/_error_handling.py +146 -0
- package/skills/gemini-imagegen/scripts/compose_images.py +150 -0
- package/skills/gemini-imagegen/scripts/edit_image.py +137 -0
- package/skills/gemini-imagegen/scripts/gemini_images.py +256 -0
- package/skills/gemini-imagegen/scripts/generate_image.py +147 -0
- package/skills/gemini-imagegen/scripts/multi_turn_chat.py +223 -0
- package/skills/gemini-imagegen/scripts/test_error_handling.py +179 -0
- package/skills/git-worktree/SKILL.md +534 -0
- package/skills/git-worktree/scripts/git-repo-readiness-diag.sh +98 -0
- package/skills/git-worktree/scripts/worktree-manager.sh +4773 -0
- package/skills/git-worktree/test/create-from-origin-main.test.sh +116 -0
- package/skills/git-worktree/test/lease-protects-active.test.sh +1056 -0
- package/skills/git-worktree/test/no-repo-fail-loud.test.sh +88 -0
- package/skills/git-worktree/test/orphan-reaper-honest-count.test.sh +379 -0
- package/skills/git-worktree/test/reap-archive-persistence.test.sh +725 -0
- package/skills/git-worktree/test/stale-lock-sweep.test.sh +176 -0
- package/skills/go/SKILL.md +54 -0
- package/skills/growth/SKILL.md +164 -0
- package/skills/harvest-debt/SKILL.md +78 -0
- package/skills/harvest-debt/scripts/harvest-debt.sh +114 -0
- package/skills/heal-skill/SKILL.md +173 -0
- package/skills/help/SKILL.md +46 -0
- package/skills/incident/NOTICE +39 -0
- package/skills/incident/SKILL.md +395 -0
- package/skills/incident/scripts/dry-run.sh +448 -0
- package/skills/incident/scripts/redact-engine.py +412 -0
- package/skills/incident/scripts/redact-sentinel.sh +44 -0
- package/skills/incident/templates/pir.md +139 -0
- package/skills/incident/test/fixtures/dry-run-incident.json +26 -0
- package/skills/incident/test/fixtures/dry-run-secret-leak.json +26 -0
- package/skills/incident/test/fixtures/legacy-bash-scanner.sh +82 -0
- package/skills/incident/test/fixtures/positive-corpus.md +87 -0
- package/skills/incident/test/redact-sentinel.test.sh +1420 -0
- package/skills/invoice/SKILL.md +206 -0
- package/skills/kb-glossary/SKILL.md +71 -0
- package/skills/kb-glossary/references/glossary-format.md +111 -0
- package/skills/kb-glossary/references/rejected-request-register.md +115 -0
- package/skills/kb-search/SKILL.md +276 -0
- package/skills/kb-search/scripts/kb-search-cache.sh +123 -0
- package/skills/legal-audit/SKILL.md +161 -0
- package/skills/legal-generate/NOTICE +242 -0
- package/skills/legal-generate/SKILL.md +244 -0
- package/skills/legal-generate/references/templates/advisor-agreement/template.md +12 -0
- package/skills/legal-generate/references/templates/business-associate-agreement/template.md +112 -0
- package/skills/legal-generate/references/templates/cookie-notice/template.md +82 -0
- package/skills/legal-generate/references/templates/dpa-global/template.md +439 -0
- package/skills/legal-generate/references/templates/dpa-us/template.md +222 -0
- package/skills/legal-generate/references/templates/employee-offer-letter/template.md +75 -0
- package/skills/legal-generate/references/templates/master-services-agreement/template.md +252 -0
- package/skills/legal-generate/references/templates/mutual-nda/template.md +66 -0
- package/skills/legal-generate/references/templates/one-way-nda/template.md +38 -0
- package/skills/legal-generate/references/templates/privacy-policy-gdpr/template.md +427 -0
- package/skills/legal-generate/references/templates/privacy-policy-us/template.md +313 -0
- package/skills/legal-generate/references/templates/terms-of-use/template.md +75 -0
- package/skills/legal-generate/scripts/strip-vendor-credit.sh +96 -0
- package/skills/linear-fetch/SKILL.md +247 -0
- package/skills/linear-fetch/scripts/assert-no-linear-telemetry.sh +66 -0
- package/skills/linear-fetch/scripts/redact-linear-urls.sh +51 -0
- package/skills/linear-fetch/scripts/render-caller-template.sh +36 -0
- package/skills/linear-fetch/test/assert-no-linear-telemetry.test.sh +113 -0
- package/skills/linear-fetch/test/parity.test.sh +112 -0
- package/skills/linear-fetch/test/persist-safe-integration.test.sh +191 -0
- package/skills/linear-fetch/test/redact-linear-urls.test.sh +226 -0
- package/skills/merge-pr/SKILL.md +668 -0
- package/skills/model-launch-review/SKILL.md +255 -0
- package/skills/model-launch-review/scripts/audit-models.sh +501 -0
- package/skills/one-shot/SKILL.md +316 -0
- package/skills/one-shot/references/token-discipline.md +74 -0
- package/skills/operator-bootstrap/SKILL.md +412 -0
- package/skills/operator-bootstrap/template.sh +439 -0
- package/skills/operator-digest/SKILL.md +287 -0
- package/skills/operator-digest/assets/operator-digest.workflow.yml +175 -0
- package/skills/operator-digest/scripts/digest-scrub.sh +119 -0
- package/skills/operator-digest/scripts/provision-operator-digest-repo.sh +147 -0
- package/skills/operator-rephrase/SKILL.md +98 -0
- package/skills/pencil-setup/SKILL.md +201 -0
- package/skills/pencil-setup/scripts/check_deps.sh +556 -0
- package/skills/pencil-setup/scripts/copy_adapter.sh +80 -0
- package/skills/pencil-setup/scripts/package-lock.json +1172 -0
- package/skills/pencil-setup/scripts/package.json +14 -0
- package/skills/pencil-setup/scripts/pencil-error-enrichment.mjs +21 -0
- package/skills/pencil-setup/scripts/pencil-mcp-adapter.mjs +733 -0
- package/skills/pencil-setup/scripts/pencil-response-classify.mjs +38 -0
- package/skills/pencil-setup/scripts/pencil-save-gate.mjs +26 -0
- package/skills/pencil-setup/scripts/sanitize-filename.mjs +25 -0
- package/skills/plan/SKILL.md +1140 -0
- package/skills/plan/references/differential-migration-testing.md +185 -0
- package/skills/plan/references/plan-community-discovery.md +42 -0
- package/skills/plan/references/plan-founder-check.md +137 -0
- package/skills/plan/references/plan-functional-overlap.md +25 -0
- package/skills/plan/references/plan-host-fanout.md +51 -0
- package/skills/plan/references/plan-issue-templates.md +779 -0
- package/skills/plan/references/plan-network-outage-checklist.md +131 -0
- package/skills/plan/references/plan-scope-check.md +126 -0
- package/skills/plan/references/plan-sharp-edges.md +325 -0
- package/skills/plan/references/plan-signoff-lifecycle.md +12 -0
- package/skills/plan/references/webapp-cwv-observability.md +143 -0
- package/skills/plan-review/SKILL.md +91 -0
- package/skills/plan-review/lib/named-panel.mjs +58 -0
- package/skills/plan-review/workflows/plan-review.workflow.js +477 -0
- package/skills/postmerge/SKILL.md +642 -0
- package/skills/postmerge/references/deploy-status-debugging.md +138 -0
- package/skills/postmerge/references/graceful-degradation.md +20 -0
- package/skills/postmerge/references/sentry-error-count-delta.md +137 -0
- package/skills/preflight/SKILL.md +1553 -0
- package/skills/preflight/references/check-13-founder-check.md +286 -0
- package/skills/preflight/scripts/founder-check.py +1640 -0
- package/skills/preflight/scripts/parse-form-a.awk +107 -0
- package/skills/preflight/scripts/probe-verb-gate.sh +108 -0
- package/skills/product-roadmap/SKILL.md +357 -0
- package/skills/product-roadmap/scripts/roadmap-reconcile.sh +327 -0
- package/skills/provision-cloudflare/SKILL.md +67 -0
- package/skills/provision-cloudflare/scripts/provision-cloudflare.sh +271 -0
- package/skills/provision-doppler/SKILL.md +58 -0
- package/skills/provision-doppler/scripts/provision-doppler.sh +358 -0
- package/skills/provision-github/SKILL.md +59 -0
- package/skills/provision-github/scripts/provision-github.sh +300 -0
- package/skills/provision-hetzner/SKILL.md +76 -0
- package/skills/provision-hetzner/scripts/provision-hetzner.sh +262 -0
- package/skills/provision-hetzner/test/fixture/knowledge-base/legal/tenant-dpa-register.md +26 -0
- package/skills/provision-hetzner/test/fixture/provision-hetzner-dry-run.golden +34 -0
- package/skills/provision-hetzner/test/provision-hetzner-characterization.test.sh +227 -0
- package/skills/qa/SKILL.md +263 -0
- package/skills/qa/references/browser-preflight.md +22 -0
- package/skills/questionnaire-generate/SKILL.md +328 -0
- package/skills/questionnaire-generate/references/questionnaire.template +60 -0
- package/skills/rclone/SKILL.md +162 -0
- package/skills/rclone/scripts/check_setup.sh +63 -0
- package/skills/release-announce/SKILL.md +65 -0
- package/skills/release-docs/SKILL.md +92 -0
- package/skills/reproduce-bug/SKILL.md +358 -0
- package/skills/resolve-debt/SKILL.md +85 -0
- package/skills/resolve-debt/scripts/resolve-debt.py +584 -0
- package/skills/resolve-parallel/SKILL.md +45 -0
- package/skills/resolve-parallel/workflows/resolve-parallel.workflow.js +415 -0
- package/skills/resolve-pr-parallel/SKILL.md +68 -0
- package/skills/resolve-pr-parallel/workflows/resolve-pr-parallel.workflow.js +419 -0
- package/skills/resolve-todo-parallel/SKILL.md +57 -0
- package/skills/resolve-todo-parallel/workflows/resolve-todo-parallel.workflow.js +398 -0
- package/skills/review/SKILL.md +1621 -0
- package/skills/review/references/anti-slop-scanner-hook.md +40 -0
- package/skills/review/references/defect-classes-migrations.md +9 -0
- package/skills/review/references/generated-input-oracle-surfaces.md +15 -0
- package/skills/review/references/review-e2e-testing.md +116 -0
- package/skills/review/references/review-todo-structure.md +165 -0
- package/skills/review/references/risk-tier-and-fix-rounds.md +95 -0
- package/skills/review/references/semgrep-custom-rules.yaml +174 -0
- package/skills/review/references/ultrathink-phases.md +98 -0
- package/skills/review/references/wfs.md +6 -0
- package/skills/review/scripts/emit-review-trailer.sh +499 -0
- package/skills/review/scripts/ensure-semgrep.sh +99 -0
- package/skills/review/scripts/fix-round-seats.sh +197 -0
- package/skills/review/test/emit-review-trailer.test.sh +387 -0
- package/skills/review/test/ensure-semgrep.test.sh +111 -0
- package/skills/review/test/fix-round-seats.test.sh +237 -0
- package/skills/review/workflows/README.md +147 -0
- package/skills/review/workflows/review.workflow.js +667 -0
- package/skills/schedule/SKILL.md +796 -0
- package/skills/seo-aeo/SKILL.md +139 -0
- package/skills/seo-aeo/scripts/validate-csp.sh +233 -0
- package/skills/seo-aeo/scripts/validate-seo.sh +262 -0
- package/skills/ship/SKILL.md +3022 -0
- package/skills/ship/references/adr-ordinal-collision.md +47 -0
- package/skills/ship/references/affected-gate-contract.md +115 -0
- package/skills/ship/references/ci-run-diagnosis.md +29 -0
- package/skills/ship/references/ci-workflow-authoring.md +68 -0
- package/skills/ship/references/counsel-review-clo-attestation.md +38 -0
- package/skills/ship/references/cto-ruling-armed-push.md +5 -0
- package/skills/ship/references/decision-challenges-render.md +71 -0
- package/skills/ship/references/detached-battery-verdict.md +13 -0
- package/skills/ship/references/feature-tweet-draft.md +42 -0
- package/skills/ship/references/followthrough-issue-body-template.md +47 -0
- package/skills/ship/references/followthrough-stub-template.sh +92 -0
- package/skills/ship/references/merge-queue-dequeue.md +39 -0
- package/skills/ship/references/operator-holds.md +149 -0
- package/skills/ship/references/pipeline-tally-render.md +43 -0
- package/skills/ship/references/pr-overlap.md +153 -0
- package/skills/ship/references/queue-mode.md +7 -0
- package/skills/ship/references/ready-run-wait.md +36 -0
- package/skills/ship/references/red-on-main-quarantine.md +110 -0
- package/skills/ship/references/register-update-pr-pattern.md +88 -0
- package/skills/ship/references/settle-then-admin-merge.md +130 -0
- package/skills/ship/references/supabase-column-probe.md +13 -0
- package/skills/ship/scripts/auto-close-scan.sh +76 -0
- package/skills/ship/scripts/battery-owed.sh +403 -0
- package/skills/ship/scripts/hold-gate-eval.sh +410 -0
- package/skills/ship/scripts/net-issue-flow.sh +665 -0
- package/skills/ship/scripts/pr-overlap-preflight.sh +483 -0
- package/skills/ship/scripts/ship-pir-action-items-gate.sh +246 -0
- package/skills/ship/scripts/technical-ruling-gate.sh +444 -0
- package/skills/skill-creator/SKILL.md +299 -0
- package/skills/skill-creator/references/api-security.md +248 -0
- package/skills/skill-creator/references/authoring-levers.md +110 -0
- package/skills/skill-creator/references/be-clear-and-direct.md +587 -0
- package/skills/skill-creator/references/best-practices.md +431 -0
- package/skills/skill-creator/references/common-patterns.md +639 -0
- package/skills/skill-creator/references/core-principles.md +193 -0
- package/skills/skill-creator/references/executable-code.md +188 -0
- package/skills/skill-creator/references/iteration-and-testing.md +509 -0
- package/skills/skill-creator/references/official-spec.md +193 -0
- package/skills/skill-creator/references/recommended-structure.md +180 -0
- package/skills/skill-creator/references/skill-structure.md +396 -0
- package/skills/skill-creator/references/using-scripts.md +122 -0
- package/skills/skill-creator/references/using-templates.md +120 -0
- package/skills/skill-creator/references/workflows-and-validation.md +541 -0
- package/skills/skill-creator/scripts/init_skill.py +322 -0
- package/skills/skill-creator/scripts/package_skill.py +110 -0
- package/skills/skill-creator/scripts/quick_validate.py +64 -0
- package/skills/skill-creator/templates/router-skill.md +73 -0
- package/skills/skill-creator/templates/simple-skill.md +34 -0
- package/skills/skill-creator/workflows/add-reference.md +96 -0
- package/skills/skill-creator/workflows/add-script.md +104 -0
- package/skills/skill-creator/workflows/add-template.md +83 -0
- package/skills/skill-creator/workflows/add-workflow.md +128 -0
- package/skills/skill-creator/workflows/audit-skill.md +159 -0
- package/skills/skill-creator/workflows/create-domain-expertise-skill.md +623 -0
- package/skills/skill-creator/workflows/create-new-skill.md +207 -0
- package/skills/skill-creator/workflows/get-guidance.md +134 -0
- package/skills/skill-creator/workflows/upgrade-to-router.md +170 -0
- package/skills/skill-creator/workflows/verify-skill.md +226 -0
- package/skills/skill-security-scan/SKILL.md +145 -0
- package/skills/skill-security-scan/references/disclaimer.md +21 -0
- package/skills/skill-security-scan/references/first-party-allowlist.yaml +38 -0
- package/skills/skill-security-scan/references/override-artifact-schema.json +68 -0
- package/skills/skill-security-scan/references/override-mechanism.md +171 -0
- package/skills/skill-security-scan/references/redirect-domains.yaml +27 -0
- package/skills/skill-security-scan/references/regex-patterns.md +136 -0
- package/skills/skill-security-scan/references/rules/code-exec.yaml +70 -0
- package/skills/skill-security-scan/references/rules/filesystem-boundary.yaml +29 -0
- package/skills/skill-security-scan/references/rules/manifest.yaml +44 -0
- package/skills/skill-security-scan/references/rules/supply-chain.yaml +36 -0
- package/skills/skill-security-scan/references/scan-meta-schema.json +63 -0
- package/skills/skill-security-scan/references/test-fixtures/clean-soleur-style.skill.md +23 -0
- package/skills/skill-security-scan/references/test-fixtures/clean-third-party.skill.md +26 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-codeexec.skill.md +23 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-curl-pipe-bash.skill.md +69 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-prompt-injection.skill.md +17 -0
- package/skills/skill-security-scan/references/test-fixtures/malicious-telemetry-beacon.skill.md +23 -0
- package/skills/skill-security-scan/references/typosquat-targets.yaml +65 -0
- package/skills/skill-security-scan/scripts/check-codeexec.sh +41 -0
- package/skills/skill-security-scan/scripts/check-filesystem-boundary.sh +19 -0
- package/skills/skill-security-scan/scripts/check-prompt-injection.sh +95 -0
- package/skills/skill-security-scan/scripts/check-supply-chain.sh +219 -0
- package/skills/skill-security-scan/scripts/check-telemetry-surface.sh +126 -0
- package/skills/skill-security-scan/scripts/lib.sh +197 -0
- package/skills/skill-security-scan/scripts/parse-override.sh +231 -0
- package/skills/skill-security-scan/scripts/run-scan.sh +342 -0
- package/skills/skill-security-scan/scripts/run-self-test.sh +95 -0
- package/skills/skill-security-scan/test/argv-ceiling.test.sh +180 -0
- package/skills/skill-security-scan/test/meta-dir-reap.test.sh +411 -0
- package/skills/skill-security-scan/test/parse-override.test.sh +607 -0
- package/skills/skill-security-scan/test/redact-pii-ghs-shape.test.sh +251 -0
- package/skills/social-distribute/SKILL.md +485 -0
- package/skills/spec-templates/SKILL.md +274 -0
- package/skills/sync/SKILL.md +49 -0
- package/skills/test-browser/SKILL.md +464 -0
- package/skills/test-browser/references/feature-map.md +161 -0
- package/skills/test-fix-loop/SKILL.md +159 -0
- package/skills/test-fix-loop/references/determinism-checklist.md +154 -0
- package/skills/triage/SKILL.md +402 -0
- package/skills/trigger-cron/SKILL.md +136 -0
- package/skills/trigger-cron/scripts/trigger.sh +198 -0
- package/skills/user-set-role/SKILL.md +147 -0
- package/skills/user-set-role/scripts/set-role.sh +218 -0
- package/skills/user-story-writer/SKILL.md +77 -0
- package/skills/ux-audit/SKILL.md +251 -0
- package/skills/ux-audit/references/finding.schema.json +62 -0
- package/skills/ux-audit/references/route-list.yaml +95 -0
- package/skills/ux-audit/scripts/bot-fixture.ts +270 -0
- package/skills/ux-audit/scripts/bot-signin.ts +135 -0
- package/skills/ux-audit/scripts/dedup-hash.ts +46 -0
- package/skills/work/SKILL.md +1479 -0
- package/skills/work/references/end-of-work-resume.md +7 -0
- package/skills/work/references/hook-test-main-cwd.md +24 -0
- package/skills/work/references/key-principles.md +83 -0
- package/skills/work/references/property-testing.md +122 -0
- package/skills/work/references/sql-security-definer-rpc-scaffold.sql +78 -0
- package/skills/work/references/work-agent-teams.md +97 -0
- package/skills/work/references/work-lifecycle-parallel.md +147 -0
- package/skills/work/references/work-lockfile-bumps.md +97 -0
- package/skills/work/references/work-scratch-sandboxes.md +212 -0
- package/skills/work/references/work-subagent-fanout.md +61 -0
- package/skills/work/references/work-test-harness-sharp-edges.md +73 -0
- package/skills/xcode-test/SKILL.md +360 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Emit the machine-readable "a review actually ran on this branch" signal (#6724).
|
|
3
|
+
#
|
|
4
|
+
# WHY THIS IS A SCRIPT AND NOT A PROSE INSTRUCTION
|
|
5
|
+
#
|
|
6
|
+
# The pre-existing convention was a sentence in review/SKILL.md telling the
|
|
7
|
+
# agent to commit review artifacts. Its measured compliance is zero on
|
|
8
|
+
# zero-finding branches, because the same skill explicitly says:
|
|
9
|
+
#
|
|
10
|
+
# "If there are no local changes, skip the commit (this is the expected
|
|
11
|
+
# case — review's primary output is GitHub issues, which are remote-only)."
|
|
12
|
+
#
|
|
13
|
+
# So the cleanest branches — the ones where review found nothing — produce no
|
|
14
|
+
# local evidence at all. Every downstream review-evidence gate then reads
|
|
15
|
+
# "review never ran" and denies the merge, with no escape hatch. That is the
|
|
16
|
+
# P0 this script exists to close, and it is why `--allow-empty` below is
|
|
17
|
+
# load-bearing rather than a convenience: without it, a zero-finding review
|
|
18
|
+
# makes no commit, emits no trailer, and deadlocks exactly the branches that
|
|
19
|
+
# had nothing wrong with them.
|
|
20
|
+
#
|
|
21
|
+
# The trailer is emitted by a script rather than described in prose because a
|
|
22
|
+
# described `git commit` line is advisory and a script invocation is not.
|
|
23
|
+
#
|
|
24
|
+
# WHAT THIS TRAILER DOES AND DOES NOT MEAN (ADR-127)
|
|
25
|
+
#
|
|
26
|
+
# It is a BOOLEAN: "a review ran on this branch". It is NOT an attestation that
|
|
27
|
+
# the merged tree is the tree that was reviewed. Reviewing early and then
|
|
28
|
+
# pushing further commits leaves the trailer in range and the gate passes.
|
|
29
|
+
#
|
|
30
|
+
# That is deliberate, not an oversight. The consuming gate is a three-signal
|
|
31
|
+
# OR in which every leg is a boolean — the legacy `review: ` subject pattern is
|
|
32
|
+
# checked BEFORE this trailer, and Signal 3 (a labelled GitHub issue) cannot be
|
|
33
|
+
# bound to a tree at all. Content-binding this one leg would therefore close
|
|
34
|
+
# nothing: `git commit --allow-empty -m "review: x"` still satisfies the gate.
|
|
35
|
+
# Making the binding real means deleting the legacy patterns (stranding every
|
|
36
|
+
# branch reviewed before this shipped) and re-architecting Signal 3 — a much
|
|
37
|
+
# larger change, landing a re-review treadmill on a gate already denying most
|
|
38
|
+
# open PRs. Gates that block constantly get bypassed; that is how #6724 was
|
|
39
|
+
# created.
|
|
40
|
+
#
|
|
41
|
+
# Threat model: agent forgetfulness on a trusted single-operator repo. These
|
|
42
|
+
# hooks live in the operator's own checkout and are editable by the same agent
|
|
43
|
+
# they constrain, so there is no enforcement boundary to build on. A boolean is
|
|
44
|
+
# the honest instrument for that.
|
|
45
|
+
#
|
|
46
|
+
# `Reviewed-Commit:` below records the reviewed sha WITHOUT any consumer reading
|
|
47
|
+
# it, so the forensic data exists if the threat model ever changes (external
|
|
48
|
+
# contributors merging without operator review) and enforcement becomes
|
|
49
|
+
# warranted. Adding the field later would be the expensive part; enforcing a
|
|
50
|
+
# field already present is cheap.
|
|
51
|
+
#
|
|
52
|
+
# WHAT `Reviewed-Coverage:` ADDS, AND WHY IT IS NOT A CONTRADICTION OF ADR-127
|
|
53
|
+
#
|
|
54
|
+
# ADR-127 settled ONE axis: the trailer does not attest that the merged tree is
|
|
55
|
+
# the reviewed tree, and content-binding was rejected. `Reviewed-Coverage:`
|
|
56
|
+
# records a DIFFERENT axis — HOW MUCH review ran — and leaves that decision
|
|
57
|
+
# untouched.
|
|
58
|
+
#
|
|
59
|
+
# The gap it closes is measured, not hypothetical. review/SKILL.md's Rate Limit
|
|
60
|
+
# Fallback gate reads "if ANY agent returned substantive output: proceed
|
|
61
|
+
# normally with available results", which is the right call and is silent about
|
|
62
|
+
# WHICH agents did not. So a 10-agent review where every agent concurred and a
|
|
63
|
+
# review where 7 of 10 died on `529 Overloaded` — losing security-sentinel,
|
|
64
|
+
# test-design-reviewer and architecture-strategist — emit a BYTE-IDENTICAL
|
|
65
|
+
# trailer. Downstream, `/ship` reads that boolean and merges. Observed
|
|
66
|
+
# 2026-07-29 on PR #7066: 7 of 9 agents terminated early on 529s, and nothing
|
|
67
|
+
# in the repo would have recorded it.
|
|
68
|
+
#
|
|
69
|
+
# The worse shape is a review that could not spawn agents AT ALL — a harness
|
|
70
|
+
# constraint, a headless run with no agent surface. The Rate Limit Fallback gate
|
|
71
|
+
# cannot see that state, because it is defined over agents that COMPLETED and
|
|
72
|
+
# nothing ever completes. The reviewer then either does an inline pass (correct)
|
|
73
|
+
# or skips review (silent), and both emit the full-strength trailer.
|
|
74
|
+
#
|
|
75
|
+
# This field is emitted with NO consumer, by exactly the argument ADR-127 used
|
|
76
|
+
# for `Reviewed-Commit:`: adding a field once the key is in main's permanent
|
|
77
|
+
# history and read by three consumers is the expensive part. Recording it now is
|
|
78
|
+
# cheap; a future gate that wants to weight a merge by review strength — or an
|
|
79
|
+
# operator asking "was this PR actually reviewed, or reviewed-shaped?" — needs
|
|
80
|
+
# the data to already be there.
|
|
81
|
+
#
|
|
82
|
+
# It is NOT a quality score. Ten agents returning nothing useful outranks two
|
|
83
|
+
# that found a P1 on every axis this field measures. It answers one narrow
|
|
84
|
+
# question: how many of the intended reviewers actually ran.
|
|
85
|
+
#
|
|
86
|
+
# Usage:
|
|
87
|
+
# emit-review-trailer.sh [--findings <n>] [--summary <text>]
|
|
88
|
+
# [--agents-ran <n>] [--agents-expected <n>]
|
|
89
|
+
# [--agents-missing <comma-separated-names>]
|
|
90
|
+
# [--mode full|degraded|inline-fallback|sequential-fallback]
|
|
91
|
+
# [--risk-tier 'none|single-user incident|aggregate pattern']
|
|
92
|
+
#
|
|
93
|
+
# `Reviewed-Risk-Tier:` (ADR-267) records the risk tier the review panel was
|
|
94
|
+
# scaled to — the resolved 3-value enum only; `undeclared` is a classifier
|
|
95
|
+
# parse state and is rejected like any other invalid value. No consumer reads
|
|
96
|
+
# it (the ADR-127 argument: recording a field whose key is already in main's
|
|
97
|
+
# history is cheap; adding it later is the expensive part).
|
|
98
|
+
#
|
|
99
|
+
# Exit codes:
|
|
100
|
+
# 0 trailer committed and verified parseable
|
|
101
|
+
# 0 skipped (on main/master, or evidence already present for this branch)
|
|
102
|
+
# 1 commit succeeded but the trailer does not parse — see VERIFY below
|
|
103
|
+
# 2 usage / environment error
|
|
104
|
+
set -euo pipefail
|
|
105
|
+
|
|
106
|
+
# (#7797) Refuse to run under shell tracing while a live credential is set: `set -x`
|
|
107
|
+
# echoes commands AFTER expansion, so a bound credential reaches the transcript
|
|
108
|
+
# before it reaches any command. `case "$-" in *x*)` tests whether tracing is ON
|
|
109
|
+
# rather than enumerating the ways to turn it on, two of which carry no `-x`
|
|
110
|
+
# token at all.
|
|
111
|
+
case "$-" in
|
|
112
|
+
*x*)
|
|
113
|
+
if [ -n "${COVERAGE_KEY:+x}${RISK_TIER_KEY:+x}${TRAILER_KEY:+x}${FIX_ROUND_KEY:+x}${FIX_RANGE_KEY:+x}" ]; then
|
|
114
|
+
printf '[FATAL] refusing to trace with a live credential set (see #7797)\n' >&2
|
|
115
|
+
exit 78
|
|
116
|
+
fi
|
|
117
|
+
;;
|
|
118
|
+
esac
|
|
119
|
+
|
|
120
|
+
usage() {
|
|
121
|
+
cat <<'EOF'
|
|
122
|
+
Usage: emit-review-trailer.sh [--findings <n>] [--summary <text>]
|
|
123
|
+
[--agents-ran <n>] [--agents-expected <n>]
|
|
124
|
+
[--agents-missing <comma-separated-names>]
|
|
125
|
+
[--mode full|degraded|inline-fallback|sequential-fallback]
|
|
126
|
+
[--risk-tier 'none|single-user incident|aggregate pattern']
|
|
127
|
+
[--fix-round --since <sha>]
|
|
128
|
+
|
|
129
|
+
Pass --agents-ran AND --agents-expected or the trailer records
|
|
130
|
+
`Reviewed-Coverage: unknown`, and nothing downstream can distinguish a
|
|
131
|
+
full review from one where the agents that mattered never ran.
|
|
132
|
+
|
|
133
|
+
Commits an empty commit carrying the Reviewed-By-Soleur: trailer, the
|
|
134
|
+
machine-readable proof that soleur:review ran on this branch (#6724).
|
|
135
|
+
|
|
136
|
+
--fix-round (ADR-267): emits a targeted-round attestation with DIFFERENT keys
|
|
137
|
+
— `Reviewed-Fix-Round:`/`Reviewed-Fix-Range:` — and NEVER `Reviewed-Coverage:`.
|
|
138
|
+
A fix round covers only the fix-commit range; writing `full` there would be a
|
|
139
|
+
coverage overclaim on the merge gate, and the main trailer's idempotence guard
|
|
140
|
+
would swallow it anyway. Requires --since <sha> (the panel snapshot).
|
|
141
|
+
|
|
142
|
+
Exit codes:
|
|
143
|
+
0 trailer committed and verified parseable
|
|
144
|
+
0 skipped (on main/master, or evidence already present for this branch)
|
|
145
|
+
1 commit succeeded but the trailer does not parse
|
|
146
|
+
2 usage / environment error
|
|
147
|
+
EOF
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
TRAILER_KEY="Reviewed-By-Soleur"
|
|
151
|
+
COVERAGE_KEY="Reviewed-Coverage"
|
|
152
|
+
RISK_TIER_KEY="Reviewed-Risk-Tier"
|
|
153
|
+
FIX_ROUND_KEY="Reviewed-Fix-Round"
|
|
154
|
+
FIX_RANGE_KEY="Reviewed-Fix-Range"
|
|
155
|
+
FINDINGS=""
|
|
156
|
+
SUMMARY=""
|
|
157
|
+
AGENTS_RAN=""
|
|
158
|
+
AGENTS_EXPECTED=""
|
|
159
|
+
AGENTS_MISSING=""
|
|
160
|
+
MODE=""
|
|
161
|
+
RISK_TIER=""
|
|
162
|
+
FIX_ROUND=0
|
|
163
|
+
FIX_SINCE=""
|
|
164
|
+
|
|
165
|
+
while [[ $# -gt 0 ]]; do
|
|
166
|
+
case "$1" in
|
|
167
|
+
--findings) FINDINGS="${2:?--findings needs a value}"; shift 2 ;;
|
|
168
|
+
--summary) SUMMARY="${2:?--summary needs a value}"; shift 2 ;;
|
|
169
|
+
--agents-ran) AGENTS_RAN="${2:?--agents-ran needs a value}"; shift 2 ;;
|
|
170
|
+
--agents-expected) AGENTS_EXPECTED="${2:?--agents-expected needs a value}"; shift 2 ;;
|
|
171
|
+
--agents-missing) AGENTS_MISSING="${2:?--agents-missing needs a value}"; shift 2 ;;
|
|
172
|
+
--mode) MODE="${2:?--mode needs a value}"; shift 2 ;;
|
|
173
|
+
--risk-tier) RISK_TIER="${2:?--risk-tier needs a value}"; shift 2 ;;
|
|
174
|
+
--fix-round) FIX_ROUND=1; shift ;;
|
|
175
|
+
--since) FIX_SINCE="${2:?--since needs a value}"; shift 2 ;;
|
|
176
|
+
-h|--help) usage; exit 0 ;;
|
|
177
|
+
*) echo "emit-review-trailer: unknown argument '$1'" >&2; exit 2 ;;
|
|
178
|
+
esac
|
|
179
|
+
done
|
|
180
|
+
|
|
181
|
+
# Validate the coverage inputs BEFORE committing anything. A malformed count
|
|
182
|
+
# would land in main's permanent history as an unparseable coverage claim, which
|
|
183
|
+
# is the same "looks like evidence to a human, invisible to a consumer" defect
|
|
184
|
+
# the VERIFY block at the bottom exists to prevent — just on a different field.
|
|
185
|
+
for _pair in "AGENTS_RAN:$AGENTS_RAN" "AGENTS_EXPECTED:$AGENTS_EXPECTED"; do
|
|
186
|
+
_name="${_pair%%:*}"; _val="${_pair#*:}"
|
|
187
|
+
if [[ -n "$_val" && ! "$_val" =~ ^[0-9]+$ ]]; then
|
|
188
|
+
echo "emit-review-trailer: --${_name,,} must be a non-negative integer (got '${_val}')" >&2
|
|
189
|
+
exit 2
|
|
190
|
+
fi
|
|
191
|
+
done
|
|
192
|
+
# `sequential-fallback` is distinct from `inline-fallback`: the former means the
|
|
193
|
+
# plugin subagent surface was unavailable (a Devin Cloud session) so the review
|
|
194
|
+
# roles ran sequentially inline, the latter that there was no agent surface at
|
|
195
|
+
# all. Both are degraded coverage, but a consumer weighting review strength can
|
|
196
|
+
# legitimately score them differently.
|
|
197
|
+
if [[ -n "$MODE" && ! "$MODE" =~ ^(full|degraded|inline-fallback|sequential-fallback)$ ]]; then
|
|
198
|
+
echo "emit-review-trailer: --mode must be one of full|degraded|inline-fallback|sequential-fallback (got '${MODE}')" >&2
|
|
199
|
+
exit 2
|
|
200
|
+
fi
|
|
201
|
+
# Only the resolved 3-value enum reaches main's history — `undeclared` is a
|
|
202
|
+
# classifier parse state, rejected here like any other invalid token (ADR-267).
|
|
203
|
+
if [[ -n "$RISK_TIER" && ! "$RISK_TIER" =~ ^(none|single-user incident|aggregate pattern)$ ]]; then
|
|
204
|
+
echo "emit-review-trailer: --risk-tier must be one of 'none'|'single-user incident'|'aggregate pattern' (got '${RISK_TIER}')" >&2
|
|
205
|
+
exit 2
|
|
206
|
+
fi
|
|
207
|
+
# `ran > expected` is a contradiction, and silently accepting it would let the
|
|
208
|
+
# field overclaim in exactly the direction that matters.
|
|
209
|
+
if [[ -n "$AGENTS_RAN" && -n "$AGENTS_EXPECTED" && "$AGENTS_RAN" -gt "$AGENTS_EXPECTED" ]]; then
|
|
210
|
+
echo "emit-review-trailer: --agents-ran ($AGENTS_RAN) exceeds --agents-expected ($AGENTS_EXPECTED)" >&2
|
|
211
|
+
exit 2
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
# DERIVE the mode rather than trusting the caller's label where the counts
|
|
215
|
+
# already answer it. A caller that passes `--mode full` alongside `--agents-ran 2
|
|
216
|
+
# --agents-expected 10` is either confused or overclaiming; the counts win.
|
|
217
|
+
#
|
|
218
|
+
# Exception: `sequential-fallback` is NOT a count axis — it attests that the
|
|
219
|
+
# plugin subagent surface was unavailable and the roles ran inline. A cloud
|
|
220
|
+
# review that ran all N roles sequentially passes N/N, which counts alone would
|
|
221
|
+
# "upgrade" to `full` — silently defeating the /ship gate that keys on the
|
|
222
|
+
# sequential-fallback prefix. An explicit `--mode sequential-fallback` survives
|
|
223
|
+
# derivation; the counts still annotate the coverage string.
|
|
224
|
+
if [[ -n "$AGENTS_RAN" && -n "$AGENTS_EXPECTED" && "$MODE" != "sequential-fallback" ]]; then
|
|
225
|
+
if [[ "$AGENTS_RAN" -eq 0 ]]; then
|
|
226
|
+
MODE="inline-fallback"
|
|
227
|
+
elif [[ "$AGENTS_RAN" -lt "$AGENTS_EXPECTED" ]]; then
|
|
228
|
+
MODE="degraded"
|
|
229
|
+
else
|
|
230
|
+
MODE="full"
|
|
231
|
+
fi
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
# UNKNOWN is the honest default, and it is deliberately not "full". A caller that
|
|
235
|
+
# does not pass the flags has told us nothing about coverage, and defaulting an
|
|
236
|
+
# absent measurement to the strongest value is how a field like this becomes
|
|
237
|
+
# decorative — every legacy call site would silently read as a 10-agent review.
|
|
238
|
+
COVERAGE_VALUE="unknown"
|
|
239
|
+
if [[ -n "$AGENTS_RAN" && -n "$AGENTS_EXPECTED" ]]; then
|
|
240
|
+
COVERAGE_VALUE="${MODE} ${AGENTS_RAN}/${AGENTS_EXPECTED} agents"
|
|
241
|
+
if [[ -n "$AGENTS_MISSING" ]]; then
|
|
242
|
+
# Commas separate names; keep them, they cannot break trailer parsing (only a
|
|
243
|
+
# newline or a non-`Key: value` line can).
|
|
244
|
+
COVERAGE_VALUE="${COVERAGE_VALUE} (missing: ${AGENTS_MISSING})"
|
|
245
|
+
fi
|
|
246
|
+
elif [[ -n "$MODE" ]]; then
|
|
247
|
+
COVERAGE_VALUE="$MODE"
|
|
248
|
+
fi
|
|
249
|
+
# Newlines would split the final paragraph and void every trailer below this one.
|
|
250
|
+
COVERAGE_VALUE="${COVERAGE_VALUE//$'\n'/ }"
|
|
251
|
+
|
|
252
|
+
# --fix-round/--since pairing: the flag means nothing without an explicit
|
|
253
|
+
# panel-snapshot sha (the merge-base fallback would scope the "targeted" round
|
|
254
|
+
# to the whole branch — the overclaim this key set exists to prevent), and
|
|
255
|
+
# --since outside --fix-round is a stranded operand.
|
|
256
|
+
if [[ "$FIX_ROUND" -eq 1 && -z "$FIX_SINCE" ]]; then
|
|
257
|
+
echo "emit-review-trailer: --fix-round requires --since <sha>" >&2
|
|
258
|
+
exit 2
|
|
259
|
+
fi
|
|
260
|
+
if [[ "$FIX_ROUND" -eq 0 && -n "$FIX_SINCE" ]]; then
|
|
261
|
+
echo "emit-review-trailer: --since requires --fix-round" >&2
|
|
262
|
+
exit 2
|
|
263
|
+
fi
|
|
264
|
+
|
|
265
|
+
if ! git rev-parse --git-dir >/dev/null 2>&1; then
|
|
266
|
+
echo "emit-review-trailer: not a git repository" >&2
|
|
267
|
+
exit 2
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
if [[ "$FIX_ROUND" -eq 1 ]] && ! git rev-parse --verify --quiet "${FIX_SINCE}^{commit}" >/dev/null 2>&1; then
|
|
271
|
+
echo "emit-review-trailer: --since '${FIX_SINCE}' does not resolve to a commit" >&2
|
|
272
|
+
exit 2
|
|
273
|
+
fi
|
|
274
|
+
# Canonicalize to the full sha — rev expressions like HEAD~2 would otherwise
|
|
275
|
+
# land in permanent history and alias the idempotence key. Then prove the base
|
|
276
|
+
# is an ANCESTOR of HEAD: a stale sha still resolves post-rebase but computes a
|
|
277
|
+
# range over unrelated history.
|
|
278
|
+
if [[ "$FIX_ROUND" -eq 1 ]]; then
|
|
279
|
+
FIX_SINCE="$(git rev-parse "$FIX_SINCE")"
|
|
280
|
+
git merge-base --is-ancestor "$FIX_SINCE" HEAD 2>/dev/null || {
|
|
281
|
+
echo "emit-review-trailer: --since ${FIX_SINCE} is not an ancestor of HEAD" >&2
|
|
282
|
+
echo " (a rebase may have invalidated the panel snapshot — recover the base per references/risk-tier-and-fix-rounds.md)" >&2
|
|
283
|
+
exit 2
|
|
284
|
+
}
|
|
285
|
+
fi
|
|
286
|
+
|
|
287
|
+
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)
|
|
288
|
+
if [[ -z "$BRANCH" ]]; then
|
|
289
|
+
echo "emit-review-trailer: could not resolve branch" >&2
|
|
290
|
+
exit 2
|
|
291
|
+
fi
|
|
292
|
+
|
|
293
|
+
# Never emit on main/master or in detached HEAD: nothing to mark there. The gate
|
|
294
|
+
# reads the merged PR's own head (#8778), so the trailer must land on the PR's
|
|
295
|
+
# branch — run this from that checkout, then push.
|
|
296
|
+
if [[ "$BRANCH" == "main" || "$BRANCH" == "master" || "$BRANCH" == "HEAD" ]]; then
|
|
297
|
+
echo "emit-review-trailer: on '$BRANCH' — nothing to mark, skipping."
|
|
298
|
+
exit 0
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
# Resolve the branch's base ref explicitly. `origin/main..HEAD` is the right
|
|
302
|
+
# scope in the real repo, but silently degrades to an ERROR — and therefore to
|
|
303
|
+
# an empty result — anywhere that ref is absent (throwaway fixtures, clones
|
|
304
|
+
# with a different default branch, detached CI checkouts). An empty result
|
|
305
|
+
# reads identically to "no trailer yet", so the idempotence check below would
|
|
306
|
+
# fail open and stack a duplicate empty commit on every invocation. Falling
|
|
307
|
+
# back to the whole of HEAD is the conservative direction: it can only ever
|
|
308
|
+
# suppress an extra commit, never emit a spurious one.
|
|
309
|
+
BASE_REF=""
|
|
310
|
+
for cand in origin/main origin/master main master; do
|
|
311
|
+
if git rev-parse --verify --quiet "$cand" >/dev/null 2>&1; then BASE_REF="$cand"; break; fi
|
|
312
|
+
done
|
|
313
|
+
if [[ -n "$BASE_REF" ]] && [[ "$(git rev-parse "$BASE_REF")" != "$(git rev-parse HEAD)" ]]; then
|
|
314
|
+
SCOPE="${BASE_REF}..HEAD"
|
|
315
|
+
else
|
|
316
|
+
SCOPE="HEAD"
|
|
317
|
+
fi
|
|
318
|
+
|
|
319
|
+
# Idempotence: if this branch already carries the trailer, a second review pass
|
|
320
|
+
# should not stack duplicate empty commits. Scoped to commits unique to the
|
|
321
|
+
# branch, for the same reason the gate is (see below).
|
|
322
|
+
# Fix-round idempotence is keyed on the full reviewed RANGE, not the branch
|
|
323
|
+
# trailer: the main-panel trailer is expected to exist already, so the
|
|
324
|
+
# branch-level skip would make every fix-round emission unreachable — and a
|
|
325
|
+
# left-edge-only match would swallow a SECOND round covering further commits.
|
|
326
|
+
# The right edge is the newest commit WITHOUT a review-attestation trailer —
|
|
327
|
+
# matched on trailers, not subjects, because `review: <summary> (P<N>)` is also
|
|
328
|
+
# this repo's prescribed FIX-commit subject (SKILL.md) and a subject filter
|
|
329
|
+
# would over-exclude real fixes, collapsing the recorded range and re-swallowing
|
|
330
|
+
# the second-round attestation this keying exists to preserve.
|
|
331
|
+
if [[ "$FIX_ROUND" -eq 1 ]]; then
|
|
332
|
+
# The walk is scoped to the round's range (an unbounded HEAD walk into an
|
|
333
|
+
# early-exiting consumer is a SIGPIPE-under-pipefail trap on big histories),
|
|
334
|
+
# and the awk consumes ALL input (no early `exit`) for the same reason.
|
|
335
|
+
# $1 must be a full sha — a trailer VALUE on a continuation line must not be
|
|
336
|
+
# mistaken for a commit.
|
|
337
|
+
EFFECTIVE_HEAD=$(git log --format='%H %(trailers:key='"$TRAILER_KEY"',valueonly)%(trailers:key='"$FIX_ROUND_KEY"',valueonly)' "${FIX_SINCE}..HEAD" \
|
|
338
|
+
| awk 'NF == 1 && $1 ~ /^[0-9a-f]{40}$/ && !found { found = $1 } END { print found }')
|
|
339
|
+
# All-attestation range (repeat call with no new fix commits) → the effective
|
|
340
|
+
# range is empty: record since..since. Falling back to HEAD would point at
|
|
341
|
+
# the prior ATTESTATION commit, rotating the range on every call and never
|
|
342
|
+
# deduping.
|
|
343
|
+
[[ -n "$EFFECTIVE_HEAD" ]] || EFFECTIVE_HEAD="$FIX_SINCE"
|
|
344
|
+
RANGE="${FIX_SINCE}..${EFFECTIVE_HEAD}"
|
|
345
|
+
if grep -qF "$RANGE" \
|
|
346
|
+
< <(git log "$SCOPE" --format='%(trailers:key='"$FIX_RANGE_KEY"',valueonly)' 2>/dev/null); then
|
|
347
|
+
echo "emit-review-trailer: a fix-round attestation over ${RANGE} already exists — skipping."
|
|
348
|
+
exit 0
|
|
349
|
+
fi
|
|
350
|
+
elif grep -q '[^[:space:]]' \
|
|
351
|
+
< <(git log "$SCOPE" --format='%(trailers:key='"$TRAILER_KEY"',valueonly)' 2>/dev/null); then
|
|
352
|
+
# Skipping is right for a REPEATED pass and wrong when the recorded reality CHANGED — e.g. a
|
|
353
|
+
# degraded 0/N review whose agents later ran to N/N (#7220, 2026-08-04). The stale trailer then
|
|
354
|
+
# misdescribes coverage to every downstream consumer, in the direction that looks safe. To
|
|
355
|
+
# supersede, commit a trailer by hand whose final paragraph is trailers ONLY, and say in the body
|
|
356
|
+
# which commit it supersedes and why.
|
|
357
|
+
echo "emit-review-trailer: branch already carries a $TRAILER_KEY trailer (scope: $SCOPE) — skipping."
|
|
358
|
+
echo "emit-review-trailer: if coverage CHANGED since that trailer, supersede it by hand — see the comment at this line." >&2
|
|
359
|
+
exit 0
|
|
360
|
+
fi
|
|
361
|
+
|
|
362
|
+
if [[ -z "$SUMMARY" ]]; then
|
|
363
|
+
if [[ "$FIX_ROUND" -eq 1 ]]; then
|
|
364
|
+
SUMMARY="targeted fix-commit round"
|
|
365
|
+
elif [[ "$FINDINGS" == "0" ]]; then
|
|
366
|
+
SUMMARY="no findings"
|
|
367
|
+
elif [[ -n "$FINDINGS" ]]; then
|
|
368
|
+
SUMMARY="$FINDINGS finding(s) triaged"
|
|
369
|
+
else
|
|
370
|
+
SUMMARY="review complete"
|
|
371
|
+
fi
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
# The subject deliberately matches the legacy Signal 2 regex (`review: `) so
|
|
375
|
+
# this commit is recognised by gates that predate the trailer and have not been
|
|
376
|
+
# updated yet. The trailer is the durable signal; the subject is the fallback.
|
|
377
|
+
#
|
|
378
|
+
# The final paragraph is trailers ONLY. Git parses just the last contiguous
|
|
379
|
+
# block of `Token: value` lines, so a stray `Refs #6724.` there would silently
|
|
380
|
+
# void every trailer below it — including this one. Issue references therefore
|
|
381
|
+
# stay in the body prose above.
|
|
382
|
+
#
|
|
383
|
+
# `Reviewed-Commit:` records the sha under review. NO consumer reads it — see
|
|
384
|
+
# the ADR-127 note in the header. It is recorded now because adding a field
|
|
385
|
+
# later, once the key is in main's permanent history and read by three
|
|
386
|
+
# consumers, is the expensive part; enforcing a field already present is cheap.
|
|
387
|
+
REVIEWED_SHA=$(git rev-parse HEAD)
|
|
388
|
+
# The tier line is absent entirely when the flag is absent — a fabricated
|
|
389
|
+
# `unknown` literal would be a claim the caller never measured. RISK_TIER is
|
|
390
|
+
# enum-validated above, so it can never carry the newline that would split the
|
|
391
|
+
# trailers paragraph.
|
|
392
|
+
RISK_TIER_LINE=""
|
|
393
|
+
if [[ -n "$RISK_TIER" ]]; then
|
|
394
|
+
RISK_TIER_LINE="${RISK_TIER_KEY}: ${RISK_TIER}"$'\n'
|
|
395
|
+
fi
|
|
396
|
+
if [[ "$FIX_ROUND" -eq 1 ]]; then
|
|
397
|
+
# Distinct keys, never Reviewed-Coverage — a targeted round covers only the
|
|
398
|
+
# fix-commit range, and ship's gate reads Reviewed-Coverage for the BRANCH.
|
|
399
|
+
# The coverage-shaped value is kept on the round's own key so the seat counts
|
|
400
|
+
# still record.
|
|
401
|
+
# The fix-round subject deliberately does NOT match the legacy Signal-2
|
|
402
|
+
# `review(\(scope\))?: ` regex — a targeted round is not branch-level review
|
|
403
|
+
# evidence, and matching that leg would let a standalone round pass the
|
|
404
|
+
# merge gate's "did review run" signal exactly like the coverage overclaim
|
|
405
|
+
# the distinct trailer keys exist to prevent.
|
|
406
|
+
COMMIT_MSG=$(printf '%s\n\n%s\n\n%s: %s\n%s: %s\n%s: %s..%s\n%s' \
|
|
407
|
+
"review-fix-round: ${SUMMARY}" \
|
|
408
|
+
"Records that a targeted fix-commit review round ran on this branch (ADR-267). It re-reviews only the named fix range with seats mapped to the areas the fix touched; it carries no branch-level coverage claim — the main panel's Reviewed-Coverage remains the branch signal." \
|
|
409
|
+
"$FIX_ROUND_KEY" "$COVERAGE_VALUE" \
|
|
410
|
+
"Reviewed-Commit" "$REVIEWED_SHA" \
|
|
411
|
+
"$FIX_RANGE_KEY" "$FIX_SINCE" "$EFFECTIVE_HEAD" \
|
|
412
|
+
"$RISK_TIER_LINE")
|
|
413
|
+
else
|
|
414
|
+
COMMIT_MSG=$(printf '%s\n\n%s\n\n%s: soleur:review\n%s: %s\n%s%s: %s\n' \
|
|
415
|
+
"review: ${SUMMARY}" \
|
|
416
|
+
"Records that soleur:review ran on this branch (see issue 6724). Empty by design: a review that finds nothing still needs to prove it ran. This is a boolean, not an attestation that the merged tree is the reviewed tree — see ADR-127. Reviewed-Coverage records HOW MUCH review ran (a separate axis from ADR-127's tree-binding decision); 'unknown' means the caller did not measure, never that coverage was full. Reviewed-Risk-Tier records the resolved risk tier the panel was scaled to (ADR-267); absent when the caller did not resolve one." \
|
|
417
|
+
"$TRAILER_KEY" \
|
|
418
|
+
"Reviewed-Commit" "$REVIEWED_SHA" \
|
|
419
|
+
"$RISK_TIER_LINE" \
|
|
420
|
+
"$COVERAGE_KEY" "$COVERAGE_VALUE")
|
|
421
|
+
fi
|
|
422
|
+
|
|
423
|
+
# `--allow-empty` does NOT mean "empty" — it commits the INDEX, so anything
|
|
424
|
+
# staged is silently absorbed into a commit whose subject reads
|
|
425
|
+
# "review: no findings". That is reachable: review's step 2 stages artifacts and
|
|
426
|
+
# its commit is conditional, while step 3 runs unconditionally right after.
|
|
427
|
+
# Refuse rather than absorb; the caller can commit or unstage and re-run.
|
|
428
|
+
if ! git diff --cached --quiet 2>/dev/null; then
|
|
429
|
+
echo "emit-review-trailer: refusing to run with staged changes." >&2
|
|
430
|
+
echo " --allow-empty commits the index, so these would be silently absorbed" >&2
|
|
431
|
+
echo " into a commit subject 'review: ${SUMMARY}':" >&2
|
|
432
|
+
git diff --cached --name-only 2>/dev/null | sed 's/^/ /' >&2
|
|
433
|
+
echo " Commit or unstage them first, then re-run." >&2
|
|
434
|
+
exit 2
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
if ! git commit --allow-empty -q -m "$COMMIT_MSG"; then
|
|
438
|
+
echo "emit-review-trailer: git commit failed" >&2
|
|
439
|
+
exit 2
|
|
440
|
+
fi
|
|
441
|
+
|
|
442
|
+
# VERIFY: a trailer that does not parse is worse than no trailer — it looks
|
|
443
|
+
# like evidence to a human reading the log and is invisible to the gate that
|
|
444
|
+
# actually consumes it. This repo has shipped that exact defect before, so the
|
|
445
|
+
# script refuses to report success on an unparseable trailer.
|
|
446
|
+
if [[ "$FIX_ROUND" -eq 1 ]]; then
|
|
447
|
+
# The fix-round block must parse as trailers; the range key is the round's
|
|
448
|
+
# load-bearing field, so it is the verified one.
|
|
449
|
+
PARSED=$(git log -1 --format='%(trailers:key='"$FIX_RANGE_KEY"',valueonly)' | tr -d '[:space:]')
|
|
450
|
+
if [[ -z "$PARSED" ]]; then
|
|
451
|
+
echo "emit-review-trailer: FAILED — commit landed but '$FIX_RANGE_KEY' does not parse." >&2
|
|
452
|
+
exit 1
|
|
453
|
+
fi
|
|
454
|
+
echo "emit-review-trailer: emitted $FIX_ROUND_KEY on '$BRANCH' ($(git rev-parse --short HEAD)) over ${FIX_SINCE}.."
|
|
455
|
+
exit 0
|
|
456
|
+
fi
|
|
457
|
+
PARSED=$(git log -1 --format='%(trailers:key='"$TRAILER_KEY"',valueonly)' | tr -d '[:space:]')
|
|
458
|
+
if [[ -z "$PARSED" ]]; then
|
|
459
|
+
echo "emit-review-trailer: FAILED — commit landed but '$TRAILER_KEY' does not parse." >&2
|
|
460
|
+
echo " The final paragraph of the commit message must contain ONLY 'Token: value' lines." >&2
|
|
461
|
+
echo " Inspect with: git interpret-trailers --parse < <(git log -1 --format=%B)" >&2
|
|
462
|
+
exit 1
|
|
463
|
+
fi
|
|
464
|
+
|
|
465
|
+
# Verify the coverage key SEPARATELY. `Reviewed-By-Soleur` parsing does not imply
|
|
466
|
+
# its siblings parse: git needs the whole final paragraph to be `Key: value`
|
|
467
|
+
# lines, but a value containing a newline splits the block and voids only the
|
|
468
|
+
# keys BELOW the split — which is exactly where this one sits. Checking the first
|
|
469
|
+
# key alone would report success while the field this change exists to add is
|
|
470
|
+
# silently absent.
|
|
471
|
+
PARSED_COVERAGE=$(git log -1 --format='%(trailers:key='"$COVERAGE_KEY"',valueonly)' | tr -d '[:space:]')
|
|
472
|
+
if [[ -z "$PARSED_COVERAGE" ]]; then
|
|
473
|
+
echo "emit-review-trailer: FAILED — commit landed but '$COVERAGE_KEY' does not parse." >&2
|
|
474
|
+
echo " It is the LAST trailer, so it is the first casualty of a split final paragraph." >&2
|
|
475
|
+
echo " Inspect with: git interpret-trailers --parse < <(git log -1 --format=%B)" >&2
|
|
476
|
+
exit 1
|
|
477
|
+
fi
|
|
478
|
+
|
|
479
|
+
echo "emit-review-trailer: emitted $TRAILER_KEY on '$BRANCH' ($(git rev-parse --short HEAD))"
|
|
480
|
+
echo "emit-review-trailer: $COVERAGE_KEY: $COVERAGE_VALUE"
|
|
481
|
+
if [[ "$COVERAGE_VALUE" == "unknown" ]]; then
|
|
482
|
+
echo "emit-review-trailer: NOTE — coverage is 'unknown' because no --agents-ran/--agents-expected was passed." >&2
|
|
483
|
+
echo " This is recorded honestly, but it means nothing downstream can tell a full review from a degraded one." >&2
|
|
484
|
+
fi
|
|
485
|
+
|
|
486
|
+
# Lifecycle successor, printed at the one moment it is actionable.
|
|
487
|
+
#
|
|
488
|
+
# Emitting this trailer means review is DONE, and review is not a stopping point
|
|
489
|
+
# (rf-never-skip-qa-review-before-merging). Twice in one session (2026-09-03) the
|
|
490
|
+
# lead pushed `review:` fixes, reported status, and ended the turn — the operator
|
|
491
|
+
# had to ask "why did you stop?" both times. The rule was present and had already
|
|
492
|
+
# been routed into review/SKILL.md as prose after the first occurrence; prose was
|
|
493
|
+
# not the gap, and a second paragraph would not have closed it.
|
|
494
|
+
#
|
|
495
|
+
# So the reminder is emitted by the tool at the checkpoint instead of relied upon
|
|
496
|
+
# as recall. This is stdout, not an error: it cannot fail a pipeline, and it costs
|
|
497
|
+
# two lines at exactly the point where the next action is unambiguous.
|
|
498
|
+
echo "emit-review-trailer: NEXT → /soleur:compound, then /soleur:ship (carry the PR to MERGED)."
|
|
499
|
+
echo "emit-review-trailer: review is not a turn boundary — 'CI is running' is not a handoff."
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Ensure the semgrep CLI is on PATH AND RUNS. If missing or dead (resolves but
|
|
3
|
+
# crashes on invocation — the mise/python-latest shebang class, #9964),
|
|
4
|
+
# attempt an auto-install from the first available package manager. On success
|
|
5
|
+
# prints the path to the installed semgrep and exits 0. On failure prints a
|
|
6
|
+
# diagnostic to stderr and exits non-zero so callers can abort the review gate.
|
|
7
|
+
#
|
|
8
|
+
# Supported install paths (in order):
|
|
9
|
+
# 1. brew install semgrep (macOS / Linuxbrew)
|
|
10
|
+
# 2. pipx install semgrep (python user-env isolation)
|
|
11
|
+
# 3. python3 -m pip install --user semgrep (pip user install)
|
|
12
|
+
#
|
|
13
|
+
# Exit codes:
|
|
14
|
+
# 0 - semgrep resolves on PATH AND `semgrep --version` executes
|
|
15
|
+
# 1 - install attempted but semgrep still does not run (incl. a fresh
|
|
16
|
+
# install shadowed by a broken earlier PATH entry)
|
|
17
|
+
# 2 - no install path available (no brew, pipx, or python3 with pip) —
|
|
18
|
+
# includes the dead-shim case: resolution is not enough to count as
|
|
19
|
+
# present, so "no installer" is the honest code
|
|
20
|
+
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
|
|
23
|
+
# semgrep_works: the single success gate — resolution AND execution. A
|
|
24
|
+
# `command -v` hit is necessary but not sufficient: a resolvable-but-dead
|
|
25
|
+
# shim must fall through to the install path exactly like an absent binary
|
|
26
|
+
# (#9964). Bounded when `timeout`/`gtimeout` exists — a mandatory gate that
|
|
27
|
+
# can hang is the same worst-shape failure as a vacuous pass.
|
|
28
|
+
semgrep_works() {
|
|
29
|
+
SEMGREP_VERSION_ERR=""
|
|
30
|
+
command -v semgrep >/dev/null 2>&1 || return 1
|
|
31
|
+
local -a t=()
|
|
32
|
+
local err
|
|
33
|
+
if command -v timeout >/dev/null 2>&1; then t=(timeout -k 1 30); elif command -v gtimeout >/dev/null 2>&1; then t=(gtimeout -k 1 30); fi
|
|
34
|
+
err="$("${t[@]}" semgrep --version 2>&1)" && return 0
|
|
35
|
+
SEMGREP_VERSION_ERR="$err"
|
|
36
|
+
return 1
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
dead_shim_diag() {
|
|
40
|
+
local resolved
|
|
41
|
+
resolved="$(command -v semgrep 2>/dev/null || echo "<unresolvable>")"
|
|
42
|
+
echo "ERROR: semgrep resolves at $resolved but does not run (${SEMGREP_VERSION_ERR:-unknown error}) — a resolvable-but-dead shim (#9964)." >&2
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if semgrep_works; then
|
|
46
|
+
command -v semgrep
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
if command -v semgrep >/dev/null 2>&1; then
|
|
51
|
+
echo "semgrep resolves but does not run — treating as absent, attempting install" >&2
|
|
52
|
+
else
|
|
53
|
+
echo "semgrep not found on PATH — attempting auto-install" >&2
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
attempted=0
|
|
57
|
+
if command -v brew >/dev/null 2>&1; then
|
|
58
|
+
echo "installing via brew..." >&2
|
|
59
|
+
attempted=1
|
|
60
|
+
if brew install semgrep >&2; then
|
|
61
|
+
if semgrep_works; then command -v semgrep; exit 0; fi
|
|
62
|
+
fi
|
|
63
|
+
echo "brew install semgrep failed (or installed but still not runnable — a broken shim may be shadowing it)" >&2
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
if command -v pipx >/dev/null 2>&1; then
|
|
67
|
+
echo "installing via pipx..." >&2
|
|
68
|
+
attempted=1
|
|
69
|
+
if pipx install semgrep >&2; then
|
|
70
|
+
# pipx adds ~/.local/bin to PATH lazily; ensure binary is reachable.
|
|
71
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
72
|
+
if semgrep_works; then command -v semgrep; exit 0; fi
|
|
73
|
+
fi
|
|
74
|
+
echo "pipx install semgrep failed (or installed but still not runnable)" >&2
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
78
|
+
echo "installing via python3 -m pip --user..." >&2
|
|
79
|
+
attempted=1
|
|
80
|
+
if python3 -m pip install --user semgrep >&2; then
|
|
81
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
82
|
+
if semgrep_works; then command -v semgrep; exit 0; fi
|
|
83
|
+
fi
|
|
84
|
+
echo "pip --user install semgrep failed (or installed but still not runnable)" >&2
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
if (( attempted )); then
|
|
88
|
+
dead_shim_diag
|
|
89
|
+
echo "install path(s) ran but semgrep still does not run — remove the dead shim or fix PATH ordering" >&2
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
if command -v semgrep >/dev/null 2>&1; then
|
|
94
|
+
dead_shim_diag
|
|
95
|
+
echo "no install path available (brew, pipx, or python3-pip required) — remove the dead shim or install a package manager" >&2
|
|
96
|
+
else
|
|
97
|
+
echo "ERROR: no install path available (brew, pipx, or python3-pip required)" >&2
|
|
98
|
+
fi
|
|
99
|
+
exit 2
|