@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,383 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Stop hook: refuse a turn that ENDS on a promise it did not keep.
|
|
4
|
+
#
|
|
5
|
+
# THE DEFECT
|
|
6
|
+
# ----------
|
|
7
|
+
# A turn ends with a sentence naming the next action -- "implementing now",
|
|
8
|
+
# "I'll run those next" -- and the action never runs. The operator has to ask
|
|
9
|
+
# "why did you stop". Measured 2026-09-07: five times in one session, three of
|
|
10
|
+
# them inside the turns building this hook.
|
|
11
|
+
#
|
|
12
|
+
# Prose already covers it and already failed: `review/SKILL.md` section 6 names
|
|
13
|
+
# the shape exactly, and was read and violated repeatedly in the session it
|
|
14
|
+
# governs. This repo's record is that every hook exists BECAUSE a rule failed.
|
|
15
|
+
#
|
|
16
|
+
# Why a Stop hook: every other enforcement here fires on a tool call. This
|
|
17
|
+
# failure is the ABSENCE of one, and nothing observed the moment a turn ends.
|
|
18
|
+
#
|
|
19
|
+
# It matters more for users than for the author. The operator caught it because
|
|
20
|
+
# they can read pipeline state; a non-technical user gets a confident summary,
|
|
21
|
+
# nothing red, and a half-finished task.
|
|
22
|
+
#
|
|
23
|
+
# LOOP SAFETY -- `stop_hook_active`, not a counter
|
|
24
|
+
# ------------------------------------------------
|
|
25
|
+
# The runtime sets `stop_hook_active: true` on a stop that a hook already
|
|
26
|
+
# blocked. Honouring it means this hook blocks at most ONCE per stop-chain, so
|
|
27
|
+
# it can never wedge a session and needs no persistence.
|
|
28
|
+
#
|
|
29
|
+
# An earlier revision kept a per-session counter on disk instead, and justified
|
|
30
|
+
# it with a comment claiming the runtime "force-stops after 3 successive Stop
|
|
31
|
+
# blocks". Corrected twice, so both errors are recorded: the number was wrong
|
|
32
|
+
# (the shipped runtime uses CLAUDE_CODE_STOP_HOOK_BLOCK_CAP ?? 8), and the
|
|
33
|
+
# follow-up claim that the mechanism was UNSOURCED was also wrong -- it exists,
|
|
34
|
+
# and `stop-hook.sh`'s HARD_CAP=50 counts ralph-loop ITERATIONS, so it never
|
|
35
|
+
# contradicted it. The accurate statement: the runtime caps consecutive Stop
|
|
36
|
+
# blocks at 8, and `stop_hook_active` is the tighter per-chain bound, which is
|
|
37
|
+
# what makes a local counter redundant. The counter is still deleted, but on the
|
|
38
|
+
# real reason rather than an invented one -- it produced every defect this hook
|
|
39
|
+
# has had (correlated fixtures, cross-run state leakage, a symlink-followable
|
|
40
|
+
# state directory, and a hardlink-truncation primitive that survived its own
|
|
41
|
+
# ownership check).
|
|
42
|
+
|
|
43
|
+
# SCOPING -- the sentence, not a byte window
|
|
44
|
+
# ------------------------------------------
|
|
45
|
+
# The allow arms are tested against THE SAME SENTENCE as the promise. An earlier
|
|
46
|
+
# revision scanned a 700-byte tail for both, so a courtesy closer anywhere in
|
|
47
|
+
# the window vetoed a promise anywhere else in it: appending "Let me know if you
|
|
48
|
+
# want it different." to any of the three real instances made the hook ALLOW
|
|
49
|
+
# them. A guard that stops working when the turn is polite is inert in practice.
|
|
50
|
+
#
|
|
51
|
+
# VOCABULARY -- a sentence-initial `Paused:` / `Blocked:` label
|
|
52
|
+
# -------------------------------------------------------------
|
|
53
|
+
# Paused: <what you are waiting on>.
|
|
54
|
+
# Blocked: <what is blocking>.
|
|
55
|
+
# Plain prose, readable wherever it is shown, so nothing needs stripping. It
|
|
56
|
+
# replaced a literal `<stop>OPERATOR-GATE: ...</stop>` tag that users read as raw
|
|
57
|
+
# markup; the legacy tag is not honoured (a model still emitting it is blocked
|
|
58
|
+
# once, then released by `stop_hook_active`).
|
|
59
|
+
#
|
|
60
|
+
# Matching is anchored to the start of the FINAL sentence and needs the colon, so
|
|
61
|
+
# "the deploy was blocked by CI" or "Blocked PRs are listed below" buy nothing.
|
|
62
|
+
# A label with no content ("Blocked: none.") is a status line, not a declaration,
|
|
63
|
+
# and does not count (STOP_NOOP_RE). The reason must be ONE sentence: a pause
|
|
64
|
+
# sentence followed by a promise sentence is a promise.
|
|
65
|
+
#
|
|
66
|
+
# Deliberately NOT the marker one-shot owns:
|
|
67
|
+
# ONE_SHOT_DONE_MARKER (lib/workflow-fidelity.ts) is bound to "PR merged,
|
|
68
|
+
# release green, postmerge verified", and stop-hook.sh treats a match as a
|
|
69
|
+
# ralph-loop completion and DELETES the loop state. An earlier revision offered
|
|
70
|
+
# that marker as this hook's escape hatch, which would have taught the model to
|
|
71
|
+
# forge the pipeline's completion token on a turn that had just been blocked,
|
|
72
|
+
# and could kill a live loop. This hook owns `Paused:`/`Blocked:` and nothing else.
|
|
73
|
+
#
|
|
74
|
+
# KNOWN RESIDUALS -- this guard is NARROWER than the property it names
|
|
75
|
+
# -------------------------------------------------------------------
|
|
76
|
+
# Stated here rather than implied away, because a guard that reads complete is
|
|
77
|
+
# more dangerous than one whose limits are written down. A structural
|
|
78
|
+
# enumeration (2026-09-07) established residuals 0-6; residual 7 is a 2026-09-30
|
|
79
|
+
# scope decision, not part of that enumeration:
|
|
80
|
+
#
|
|
81
|
+
# 0. THE PARKED ARM IS NARROWER THAN ITS NAME, in ways measured by a structural
|
|
82
|
+
# enumeration (2026-09-17) rather than guessed. It catches only a turn that
|
|
83
|
+
# VOLUNTEERS the sentinel and phrases the parking inside a closed vocabulary:
|
|
84
|
+
# * omitting the label is a complete defence, and a parked turn has
|
|
85
|
+
# no other reason to emit one (it makes no promise);
|
|
86
|
+
# * off-vocabulary parking escapes -- `the merge is yours`, `awaiting
|
|
87
|
+
# approval`, `merge when you have a moment`, `the ball is in your court`;
|
|
88
|
+
# * `PARKED_AUTH_RE` is polarity-blind, so "Nothing destructive here" in the
|
|
89
|
+
# label's own sentence buys an exit;
|
|
90
|
+
# * five or more sentences after the label evict it from CLOSING, as does a
|
|
91
|
+
# fenced block, an unterminated fence, and a >8 kB message whose tail
|
|
92
|
+
# starts inside a fence (the awk toggle then reads the CLOSING fence as an
|
|
93
|
+
# opening one);
|
|
94
|
+
# * `stop_hook_active` means restating the parked sentence once clears it;
|
|
95
|
+
# * `SubagentStop` is unregistered, so a sub-agent parking its deliverable
|
|
96
|
+
# on the parent is unobserved.
|
|
97
|
+
# None is closable by widening the regex -- the assembly reads ONE STRING and
|
|
98
|
+
# never consults gh, git or pipeline state, so it cannot see that a PR is open.
|
|
99
|
+
# Written down because a guard that reads complete is worse than one whose
|
|
100
|
+
# limits are stated.
|
|
101
|
+
#
|
|
102
|
+
# 1. VOCABULARY. The predicate is a regex over a closed set of phrasings.
|
|
103
|
+
# "We'll ...", "Going to ...", "Next: ...", "The plan is to ...",
|
|
104
|
+
# "On to the ...", and any gerund outside GERUND_RE evade it. Broadened
|
|
105
|
+
# below to the highest-frequency forms; NOT complete, and cannot be.
|
|
106
|
+
# 2. EVENT COVERAGE. `Stop` does not fire on user interrupt or on an API
|
|
107
|
+
# error (that is `StopFailure`, unregistered here), and subagent turns end
|
|
108
|
+
# on `SubagentStop` (also unregistered). A promise made in a subagent's
|
|
109
|
+
# final message is unobserved.
|
|
110
|
+
# 3. INSTALLATION. .claude/settings.json registers no Stop hook, so this
|
|
111
|
+
# repo's own sessions are covered only via the plugin.
|
|
112
|
+
# 4. ONE BLOCK PER CHAIN. `stop_hook_active` means a determined turn can
|
|
113
|
+
# restate the promise on the next stop and proceed. That is deliberate --
|
|
114
|
+
# the alternative is a hook that can wedge a session.
|
|
115
|
+
# 5. TAG QUESTION. A message ending in '?' is treated as waiting on an
|
|
116
|
+
# answer, so "Implementing now. Reasonable?" buys an exit. The inverse --
|
|
117
|
+
# blocking a genuine question -- pushes the model past information it
|
|
118
|
+
# needs, which is the worse failure.
|
|
119
|
+
# 6. SELF-DISARM. A turn whose FINAL sentence starts `Paused:` or `Blocked:`
|
|
120
|
+
# satisfies the escape hatch whether or not it is a real declaration, because
|
|
121
|
+
# a label a person writes unprompted is the price of not showing them markup.
|
|
122
|
+
# Empty labels (`Blocked: none.`) are excluded; a populated one still counts.
|
|
123
|
+
# 7. WEB SESSIONS OPT OUT. This hook is operator-CLI vocabulary: its block reason
|
|
124
|
+
# instructs the model in words a chat user must never see, and the web runtime
|
|
125
|
+
# loads it anyway (see WEB RUNTIME OPT-OUT below). Accepted trade-off: the
|
|
126
|
+
# header above says the guard matters more for non-technical users, but in the
|
|
127
|
+
# web Concierge the old tag vocabulary leaked `<stop>OPERATOR-GATE` over the
|
|
128
|
+
# user's question list (a block turn still replaces the reply there).
|
|
129
|
+
# The unkept-promise duty is therefore currently UNOWNED in web: no Concierge
|
|
130
|
+
# prompt carries an end-of-turn follow-through rule. That gap is tracked in
|
|
131
|
+
# #9289 (which also covers the non-Stop plugin hooks); it is not closed here.
|
|
132
|
+
#
|
|
133
|
+
# What it DOES buy: the common case, which is a plain closing sentence naming
|
|
134
|
+
# the next action. Measured against the five real 2026-09-07 instances, it
|
|
135
|
+
# catches the three that were plain prose.
|
|
136
|
+
|
|
137
|
+
set -uo pipefail
|
|
138
|
+
|
|
139
|
+
# SUT-WRITTEN EXECUTION MARKER (test-only, opt-in via an env var production never
|
|
140
|
+
# sets). The suite's coverage floor counted lines its OWN harness appended before
|
|
141
|
+
# spawning anything, so it measured the harness and not the subject: one line --
|
|
142
|
+
# `expect() { EXPECT_ROWS=$((EXPECT_ROWS+1)); echo x >> "$LOG"; pass "$2"; }` --
|
|
143
|
+
# satisfied all three floors at once and printed their exact green-run values with
|
|
144
|
+
# the hook never spawned for any parked row.
|
|
145
|
+
#
|
|
146
|
+
# EMITTED TO STDERR, NOT WRITTEN TO A PATH. A path operand here is flagged by the
|
|
147
|
+
# P1b guard (fixture-relative-assert) as "not provably absolute": the value comes
|
|
148
|
+
# from the environment, and a `case /*)` at the use site is invisible to a scanner
|
|
149
|
+
# that reasons about BINDING. Recording it in that guard's baseline would have
|
|
150
|
+
# banked a real hazard -- a hook runs from whatever CWD the session is in, so a
|
|
151
|
+
# relative value would append into an arbitrary working tree. fd 2 is not a path,
|
|
152
|
+
# so the hazard does not exist rather than being accepted. stdout stays reserved
|
|
153
|
+
# for the block protocol; the harness counts this marker from captured stderr, so
|
|
154
|
+
# a harness that never spawns the hook still counts zero.
|
|
155
|
+
[ -n "${SOLEUR_HOOK_TRACE:-}" ] && printf 'SOLEUR_HOOK_RAN\n' >&2
|
|
156
|
+
|
|
157
|
+
# WEB RUNTIME OPT-OUT. The web Concierge loads this plugin's hooks.json through the
|
|
158
|
+
# SDK plugin binding, so this operator-CLI guard ran against end users: its block
|
|
159
|
+
# reason told the model to write `<stop>OPERATOR-GATE: ...</stop>`, which replaced
|
|
160
|
+
# a CRM question list in the chat bubble. The platform sets this variable in
|
|
161
|
+
# `buildAgentEnv` (apps/web-platform/server/agent-env.ts); it also works as an
|
|
162
|
+
# operator kill switch, mirroring SOLEUR_DISABLE_COMPACTION_HOOKS. Its position is
|
|
163
|
+
# load-bearing in ONE direction: it must sit AFTER the trace marker above (the suite
|
|
164
|
+
# counts executions through that stderr line, so an opted-out spawn is still counted
|
|
165
|
+
# as a run — moving it above the marker trips the floor). Its position relative to the
|
|
166
|
+
# jq fail-open below is behaviourally equivalent (both exit 0 silently), so it sits
|
|
167
|
+
# first only to keep an opted-out session independent of jq.
|
|
168
|
+
[[ "${SOLEUR_DISABLE_UNKEPT_PROMISE_HOOK:-0}" == "1" ]] && exit 0
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# Fail OPEN on every infrastructure problem: this must never be the reason a
|
|
172
|
+
# session cannot end.
|
|
173
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
174
|
+
HOOK_INPUT=$(cat 2>/dev/null) || exit 0
|
|
175
|
+
[[ -n "$HOOK_INPUT" ]] || exit 0
|
|
176
|
+
|
|
177
|
+
# Already blocked once in this stop-chain -- do not block again.
|
|
178
|
+
ACTIVE=$(printf '%s' "$HOOK_INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null) || exit 0
|
|
179
|
+
[[ "$ACTIVE" == "true" ]] && exit 0
|
|
180
|
+
|
|
181
|
+
LAST_MSG=$(printf '%s' "$HOOK_INPUT" | jq -r '.last_assistant_message // ""' 2>/dev/null) || exit 0
|
|
182
|
+
[[ -n "$LAST_MSG" ]] || exit 0
|
|
183
|
+
|
|
184
|
+
# Split into sentences, newest last. Markdown bullets and headings end a line
|
|
185
|
+
# without punctuation, so line breaks are sentence boundaries too.
|
|
186
|
+
# Drop fenced blocks first: wg-end-of-work-emit-resume-prompt REQUIRES a fenced
|
|
187
|
+
# resume prompt as the final block of every /work and /one-shot turn -- the very
|
|
188
|
+
# class this defect lives in. Left in, it becomes the "closing sentences" and
|
|
189
|
+
# hides the promise above it. Also drop leading markdown bullet/emphasis markers
|
|
190
|
+
# so a "Next steps:" list is not invisible to the sentence-initial anchors.
|
|
191
|
+
# Bound the input before any pipeline touches it. Only the closing sentences are
|
|
192
|
+
# ever used, and an unbounded message costs real time on every turn end
|
|
193
|
+
# (measured on the prior revision: 20 MB -> 6.5 s, 186 MB RSS). It also removes
|
|
194
|
+
# the SIGPIPE hazard below at the source.
|
|
195
|
+
BOUNDED=$(printf '%s' "$LAST_MSG" | tail -c 8000)
|
|
196
|
+
PROSE=$(printf '%s' "$BOUNDED" | awk '/^[[:space:]]*```/{f=!f; next} !f')
|
|
197
|
+
# Newlines are folded to RS so a sentence-ending period followed by a line break
|
|
198
|
+
# still splits, then folded BACK with `tr` -- not `sed`. `tr` interprets \036 as
|
|
199
|
+
# an octal escape and `sed` does not, so `sed 's/\036/\n/g'` silently matched
|
|
200
|
+
# nothing: the separators survived, the whole message stayed ONE "sentence", and
|
|
201
|
+
# per-sentence scoping was inert for any newline-separated text. Every fixture
|
|
202
|
+
# used ". " separators, so the suite could not see it.
|
|
203
|
+
SENTENCES=$(printf '%s' "$PROSE" | tr '\n' '\036' \
|
|
204
|
+
| sed 's/\([.!?]\)[[:space:]]/\1\n/g' \
|
|
205
|
+
| tr '\036' '\n' \
|
|
206
|
+
| sed 's/^[[:space:]]*//; s/^[-*+][[:space:]]*//; s/^\*\*//; s/[[:space:]]*$//' \
|
|
207
|
+
| grep -v '^$' || true)
|
|
208
|
+
[[ -n "$SENTENCES" ]] || exit 0
|
|
209
|
+
|
|
210
|
+
# Only the closing few sentences are evidence about where the turn STOPPED.
|
|
211
|
+
CLOSING=$(printf '%s' "$SENTENCES" | tail -n 4)
|
|
212
|
+
|
|
213
|
+
# THE PARKED-DELIVERABLE ARM (2026-09-17).
|
|
214
|
+
# ----------------------------------------
|
|
215
|
+
# Denies a stop that hands FINISHED WORK back for a merge/review/ship. That end
|
|
216
|
+
# state is the one `rf-never-skip-qa-review-before-merging` names: "Carry every PR
|
|
217
|
+
# to MERGED in-session; 'awaiting review'/'needs a human' as an end state defers to
|
|
218
|
+
# an operator who cannot clear it."
|
|
219
|
+
#
|
|
220
|
+
# WHY THE LABEL ALONE WAS NOT ENOUGH. The stop-label arm below exits 0 on the PRESENCE
|
|
221
|
+
# of a label, with nothing constraining what is being waited ON, so the one end state
|
|
222
|
+
# the corpus forbids bought an exit. Parking READS as diligence, which is why prose
|
|
223
|
+
# could not close it: the class was recorded 2026-08-04 and recurred 2026-09-17 with
|
|
224
|
+
# the rule in force.
|
|
225
|
+
#
|
|
226
|
+
# THE OBJECT SET IS DELIBERATELY NARROW: merge, review, ship. An earlier revision
|
|
227
|
+
# also matched `decision|approv|go-?ahead|sign-off`, and review measured it blocking
|
|
228
|
+
# 13 of 15 rule-MANDATED operator gates -- `wg-zero-agents-until-user-confirms`
|
|
229
|
+
# ("pending your go-ahead before I spawn the agents"), the API-budget disclosure,
|
|
230
|
+
# an invoice awaiting sign-off before reaching a customer, a social post awaiting
|
|
231
|
+
# approval -- while answering each with "Do it now, in THIS turn". A guard that
|
|
232
|
+
# fires on `wg-zero-agents-until-user-confirms` and replies "do it now" is worse
|
|
233
|
+
# than no guard. `hr-technical-fork-is-not-an-operator-question` is explicit that
|
|
234
|
+
# authorization, COST and SCOPE are the operator's to answer; only the delivery of
|
|
235
|
+
# reviewed work is not.
|
|
236
|
+
#
|
|
237
|
+
# PLACEMENT, both measured against the real turn rather than reasoned:
|
|
238
|
+
# * scoped to the whole closing, not `tail -n 1` -- the declaration began in one sentence
|
|
239
|
+
# and its reason ran into the next, so a last-sentence test saw only the trailing clause;
|
|
240
|
+
# * runs INDEPENDENTLY of promise detection -- a parked turn makes no promise, so
|
|
241
|
+
# an arm nested in the promise path could never fire.
|
|
242
|
+
# The declaration marker: a sentence that STARTS with `Paused:` or `Blocked:`. The
|
|
243
|
+
# sentence prep's bullet strip eats one `*` of a leading `**`, hence `[*]*`; both
|
|
244
|
+
# `**Paused**:` and `**Paused:**` match. See VOCABULARY above.
|
|
245
|
+
STOP_MARK_RE='^[*]*(paused|blocked)[*[:space:]]*:'
|
|
246
|
+
# A label whose content is empty or a negative status ("Blocked: none.").
|
|
247
|
+
STOP_NOOP_RE='^[^:]*:[*[:space:]]*((no|none|nothing|n/?a)[[:punct:][:space:]]*)?$'
|
|
248
|
+
is_stop_mark() { grep -qiE "$STOP_MARK_RE" <<<"$1" && ! grep -qiE "$STOP_NOOP_RE" <<<"$1"; }
|
|
249
|
+
|
|
250
|
+
PARKED_RE='(awaiting|waiting[[:space:]]+(on|for)|pending|needs?|requires?)[^.]{0,60}(your|operator|the[[:space:]]+operator|human|a[[:space:]]+human)[^.]{0,60}(merge|review|ship)|awaiting[[:space:]]+(review|merge)([[:space:]]|[.,;:]|$)|needs?[[:space:]]+a[[:space:]]+human([[:space:]]|[.,;:]|$)|ready[[:space:]]+(for[[:space:]]+(you|your)|to[[:space:]]+merge[[:space:]]+when[[:space:]]+you)|(yours|over[[:space:]]+to[[:space:]]+you|handing[[:space:]]+(it[[:space:]]+)?off[[:space:]]+to[[:space:]]+you)[^.]{0,40}(merge|review|ship)'
|
|
251
|
+
|
|
252
|
+
# The sanctioned pause survives: `hr-menu-option-ack-not-prod-write-auth` requires
|
|
253
|
+
# per-command confirmation before a destructive production write.
|
|
254
|
+
#
|
|
255
|
+
# SCOPED TO THE MATCHING SENTENCE, NOT THE WINDOW -- and that is this file's own
|
|
256
|
+
# documented lesson, reintroduced by the first revision of this arm and caught in
|
|
257
|
+
# review. The header's SCOPING section records that a window-scoped allow arm is
|
|
258
|
+
# what made the promise arm inert ("a courtesy closer anywhere in the window vetoed
|
|
259
|
+
# a promise anywhere else in it"). Measured on the first revision: "I revoked the
|
|
260
|
+
# old token as part of cleanup. Paused: PR #8244 is green and awaiting
|
|
261
|
+
# your merge." ALLOWED, because `revoke` appeared in an unrelated sentence.
|
|
262
|
+
PARKED_AUTH_RE='(irreversible|destroy|destructive|wipe|revoke|cutover|host[[:space:]]+replace|replace[[:space:]]+the[[:space:]]+(production[[:space:]]+)?host|per-command|prod(uction)?[[:space:]]+(write|mutation|apply))'
|
|
263
|
+
|
|
264
|
+
# ALL THREE TERMS ARE TESTED ON THE MARKER'S OWN SENTENCE, not on the window.
|
|
265
|
+
#
|
|
266
|
+
# The first revision tested them independently over $CLOSING, so they could be
|
|
267
|
+
# satisfied by THREE DIFFERENT sentences -- which is co-occurrence, not the
|
|
268
|
+
# waiting-on relationship this arm's header claims to key on. Measured in review:
|
|
269
|
+
# "The sibling PR is still awaiting review by the other team.
|
|
270
|
+
# Paused: waiting on CI run 123 for this one." -> BLOCK
|
|
271
|
+
# A legitimate in-flight CI gate, vetoed because a neighbouring sentence mentioned
|
|
272
|
+
# somebody else's review. Same shape in the other direction, and same shape the
|
|
273
|
+
# header's own SCOPING section records as what made the promise arm inert.
|
|
274
|
+
#
|
|
275
|
+
# A turn ending in a genuine QUESTION is excused here, mirroring the message-level
|
|
276
|
+
# arm further down. Residual #5 records the deliberate judgement that "forcing a
|
|
277
|
+
# real question through is the worse failure"; because this arm runs above that
|
|
278
|
+
# escape, it would otherwise reverse that judgement for labelled turns without
|
|
279
|
+
# amending the residual.
|
|
280
|
+
PARKED_SENTENCE=$(printf '%s\n' "$CLOSING" | grep -iE "$STOP_MARK_RE" | tail -n 1)
|
|
281
|
+
if [ -n "$PARKED_SENTENCE" ] &&
|
|
282
|
+
! grep -q '?' < <(printf '%s' "$PROSE" | sed 's/[[:space:]]*$//' | tail -c 2) &&
|
|
283
|
+
grep -qiE "$PARKED_RE" <<<"$PARKED_SENTENCE" &&
|
|
284
|
+
! grep -qiE "$PARKED_AUTH_RE" <<<"$PARKED_SENTENCE"; then
|
|
285
|
+
PARKED_REASON="Your Paused/Blocked line hands finished work back for a merge, review or ship. That is not a
|
|
286
|
+
legitimate gate -- it defers to someone who cannot clear it.
|
|
287
|
+
|
|
288
|
+
rf-never-skip-qa-review-before-merging: \"Carry every PR to MERGED in-session;
|
|
289
|
+
'awaiting review'/'needs a human' as an end state defers to an operator who
|
|
290
|
+
cannot clear it.\" \"Review-gated\" means /soleur:review RAN and its findings were
|
|
291
|
+
fixed -- never that a person approves.
|
|
292
|
+
|
|
293
|
+
If the review has not run, run it now and fix its findings inline. If it has, and
|
|
294
|
+
the checks are green, merge. Do it in THIS turn.
|
|
295
|
+
|
|
296
|
+
This arm is about DELIVERY only. It does not block -- and you should still stop
|
|
297
|
+
for -- any of these:
|
|
298
|
+
- an in-flight CI run, workflow or agent
|
|
299
|
+
- authorization for an irreversible production action (hr-menu-option-ack-not-prod-write-auth)
|
|
300
|
+
- COST or SCOPE, or spawning agents (hr-technical-fork-is-not-an-operator-question,
|
|
301
|
+
wg-zero-agents-until-user-confirms)
|
|
302
|
+
- an outward-facing effect that leaves the repo -- an invoice, a post, an email
|
|
303
|
+
- a genuine fork in requirements that changes what gets built"
|
|
304
|
+
jq -n --arg r "$PARKED_REASON" \
|
|
305
|
+
'{"decision":"block","reason":$r,"systemMessage":"unkept-promise-hook: finished work parked on the operator"}' 2>/dev/null \
|
|
306
|
+
|| exit 0
|
|
307
|
+
exit 0
|
|
308
|
+
fi
|
|
309
|
+
|
|
310
|
+
# Escape hatch, scanned over the CLOSING sentences only -- deliberately the same
|
|
311
|
+
# scope as the predicate.
|
|
312
|
+
#
|
|
313
|
+
# An earlier revision scanned the whole message, which was wrong twice over.
|
|
314
|
+
# (a) ASYMMETRY: a turn that merely DISCUSSED the sentinel -- documenting it,
|
|
315
|
+
# reviewing this hook, quoting a user's paste -- disarmed the guard while
|
|
316
|
+
# still closing on a promise. That silently exempted exactly the sessions
|
|
317
|
+
# that edit this file, including this PR's own turns.
|
|
318
|
+
# (b) SIGPIPE: `printf "$BIG" | grep -q` under `set -o pipefail` returns 141
|
|
319
|
+
# when grep exits on first match, so the `if` read a MATCH as a NON-match.
|
|
320
|
+
# Measured on the prior revision: a valid sentinel was ignored at >=64 KB,
|
|
321
|
+
# non-deterministically at the pipe-buffer boundary -- i.e. the only way to
|
|
322
|
+
# declare a legitimate stop failed precisely on long closing messages.
|
|
323
|
+
# Both are closed by scoping to CLOSING, which is a handful of short lines.
|
|
324
|
+
# Narrower still: the FINAL sentence. Declaring a stop is a closing act, so a
|
|
325
|
+
# sentinel merely mentioned earlier -- documenting it, reviewing this hook,
|
|
326
|
+
# quoting a paste -- no longer disarms the guard. CLOSING alone was not enough:
|
|
327
|
+
# in a two-sentence message both the mention and the promise sit inside it.
|
|
328
|
+
if is_stop_mark "$(printf '%s' "$CLOSING" | tail -n 1)"; then
|
|
329
|
+
exit 0
|
|
330
|
+
fi
|
|
331
|
+
|
|
332
|
+
# A turn ENDING in a question is waiting on an answer, whatever else it said.
|
|
333
|
+
# This one arm is message-level, not per-sentence: blocking it would push the
|
|
334
|
+
# model past a question it needs answered, and produce work built on a guess.
|
|
335
|
+
# The cost is a named residual -- a tag question ("Implementing now. Reasonable?")
|
|
336
|
+
# buys an exit. Accepted: forcing a real question through is the worse failure.
|
|
337
|
+
if grep -q '?' < <(printf '%s' "$PROSE" | sed 's/[[:space:]]*$//' | tail -c 2); then
|
|
338
|
+
exit 0
|
|
339
|
+
fi
|
|
340
|
+
|
|
341
|
+
PROMISE_RE="(i'll |i will |i am going to |i'm going to |im going to |we'll |we will |let me [a-z]+|going to [a-z]+|about to [a-z]+|next:|next step|the plan is to |on to the |time to [a-z]+)"
|
|
342
|
+
GERUND_RE='^(implementing|running|building|writing|committing|pushing|shipping|fixing|creating|adding|executing|starting|continuing|proceeding|applying|updating|wiring|merging|deploying|verifying|refactoring|drafting|opening|rebasing|patching|migrating|landing|testing|checking|investigating|finishing|queuing|spawning|handing)\b'
|
|
343
|
+
|
|
344
|
+
# Allow arms, evaluated PER SENTENCE against the sentence that carries the
|
|
345
|
+
# promise -- never against the window, which is what let a closer veto a promise
|
|
346
|
+
# it had nothing to do with.
|
|
347
|
+
# conditional : the promise is contingent on the operator
|
|
348
|
+
# pending : the promise is contingent on work already in flight
|
|
349
|
+
# `let me know` is matched by PROMISE_RE, so CONDITIONAL must be tested first.
|
|
350
|
+
CONDITIONAL_RE='(say the word|if you|once you|when you|whenever you|let me know|tell me|your call|up to you|on your (go|signal|say))'
|
|
351
|
+
PENDING_RE='(report (what|back)|(when|once|as soon as|after) (it|they|those|the (run|tests|ci|build|merge))|(they|it|those) (find|finds|land|lands|complete|completes|merge|merges|return|returns)|still running|in flight|notification arrives)'
|
|
352
|
+
|
|
353
|
+
FIRED=""
|
|
354
|
+
while IFS= read -r s; do
|
|
355
|
+
[[ -n "$s" ]] || continue
|
|
356
|
+
grep -qiE "$CONDITIONAL_RE" <<<"$s" && continue
|
|
357
|
+
grep -qiE "$PENDING_RE" <<<"$s" && continue
|
|
358
|
+
if grep -qiE "$PROMISE_RE" <<<"$s"; then
|
|
359
|
+
FIRED="a first-person commitment to act"; break
|
|
360
|
+
fi
|
|
361
|
+
if grep -qiE "$GERUND_RE" <<<"$s"; then
|
|
362
|
+
FIRED="a bare gerund announcement"; break
|
|
363
|
+
fi
|
|
364
|
+
done <<< "$CLOSING"
|
|
365
|
+
|
|
366
|
+
[[ -n "$FIRED" ]] || exit 0
|
|
367
|
+
|
|
368
|
+
REASON="Your closing text names an action you have not taken -- ${FIRED} -- and the turn is ending.
|
|
369
|
+
|
|
370
|
+
Do it now, in THIS turn. Writing the next action down is not doing it.
|
|
371
|
+
|
|
372
|
+
If the stop is legitimate, end the message with ONE plain sentence that starts with
|
|
373
|
+
the label and says why (no markup, no sentence break inside it):
|
|
374
|
+
Paused: the one thing you are waiting on.
|
|
375
|
+
Blocked: the one thing that is blocking you.
|
|
376
|
+
|
|
377
|
+
Stopping is allowed. Stopping silently is not -- an operator who cannot see the
|
|
378
|
+
pipeline has no way to tell a finished task from an abandoned one."
|
|
379
|
+
|
|
380
|
+
jq -n --arg r "$REASON" \
|
|
381
|
+
'{"decision":"block","reason":$r,"systemMessage":"unkept-promise-hook: turn ended on an unexecuted commitment"}' 2>/dev/null \
|
|
382
|
+
|| exit 0
|
|
383
|
+
exit 0
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# version-banner.sh — SessionStart (matcher: startup) one-line Soleur version banner.
|
|
3
|
+
#
|
|
4
|
+
# Prints ONE JSON object on stdout: {"systemMessage": "Soleur <vX.Y.Z | commit <sha12>[ (local checkout)]>[ — newer release vA.B.C available]"}
|
|
5
|
+
# `commit <sha12> (local checkout)` is an in-place install (a local-Folder marketplace or --plugin-dir):
|
|
6
|
+
# the resolver read the HEAD commit of the git checkout the plugin is loaded from.
|
|
7
|
+
# `systemMessage` is shown to the user and costs zero model tokens (no additionalContext).
|
|
8
|
+
#
|
|
9
|
+
# The banner itself is ON by default and makes NO network call. Only the "newer release"
|
|
10
|
+
# check is opt-in: with SOLEUR_UPDATE_CHECK=1 (exactly `1`; `0`, empty and any other value
|
|
11
|
+
# are off) the hook reads the per-install release cache and, when that cache is stale,
|
|
12
|
+
# missing or corrupt, spawns ONE detached background refresh. The hook itself never touches
|
|
13
|
+
# the network and never waits on it: it prints the cached answer now.
|
|
14
|
+
#
|
|
15
|
+
# Skips silently (exit 0, no output) when CLAUDE_PLUGIN_ROOT is unset, on the non-Claude
|
|
16
|
+
# harness markers hooks/welcome-hook.sh uses (CODEX_THREAD_ID, PLUGIN_ROOT), when
|
|
17
|
+
# SOLEUR_DISABLE_VERSION_BANNER=1, and when the installed version cannot be determined.
|
|
18
|
+
#
|
|
19
|
+
# Fails open: every path exits 0 and any error prints nothing. Plugin hooks are GLOBAL
|
|
20
|
+
# (they fire in every project), so a banner that errors or blocks would hit every session.
|
|
21
|
+
set -uo pipefail
|
|
22
|
+
case "$-" in
|
|
23
|
+
*x*) printf '[FATAL] refusing to run under xtrace: this script handles a live credential and -x would print it (see #7797)\n' >&2; exit 78 ;;
|
|
24
|
+
esac
|
|
25
|
+
# `set -u` aborts with status 1 and no ERR trap on an unbound variable; force a clean exit.
|
|
26
|
+
trap 'exit 0' EXIT
|
|
27
|
+
|
|
28
|
+
# Refresh dedupe: an atomic mkdir lock under the cache dir. It is deliberately never
|
|
29
|
+
# removed by the refresh; it simply ages out, which also rate-limits repeated attempts
|
|
30
|
+
# while offline (one attempt per LOCK_TTL_S instead of one per session).
|
|
31
|
+
LOCK_TTL_S=600
|
|
32
|
+
|
|
33
|
+
json_escape() { # escape a string for use inside a JSON string literal
|
|
34
|
+
local s="$1"
|
|
35
|
+
s="${s//\\/\\\\}"
|
|
36
|
+
s="${s//\"/\\\"}"
|
|
37
|
+
s="${s//$'\n'/ }"
|
|
38
|
+
s="${s//$'\r'/ }"
|
|
39
|
+
s="${s//$'\t'/ }"
|
|
40
|
+
printf '%s' "$s"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Spawn at most one detached background refresh. Never blocks, never prints.
|
|
44
|
+
spawn_refresh() { # <resolver> <cache_dir>
|
|
45
|
+
local resolver="$1" cache_dir="$2" lock now mtime v
|
|
46
|
+
# The resolver reports an absolute cache dir or none (HOME unset, relative XDG).
|
|
47
|
+
[[ "$cache_dir" == /* ]] || return 0
|
|
48
|
+
lock="$cache_dir/refresh.lock"
|
|
49
|
+
( umask 077; mkdir -p "$cache_dir" ) 2>/dev/null || return 0
|
|
50
|
+
# Same trust rule as the resolver: only lock inside a directory we own that is not a symlink.
|
|
51
|
+
[[ -d "$cache_dir" && -O "$cache_dir" && ! -L "$cache_dir" ]] || return 0
|
|
52
|
+
if [[ -d "$lock" ]]; then
|
|
53
|
+
now="$(date +%s)"
|
|
54
|
+
mtime="$(stat -c %Y "$lock" 2>/dev/null || stat -f %m "$lock" 2>/dev/null || echo "$now")"
|
|
55
|
+
[[ "$mtime" =~ ^[0-9]+$ ]] || mtime="$now"
|
|
56
|
+
# A future-dated lock (clock change) counts as expired, like a future-dated cache.
|
|
57
|
+
if (( now - mtime >= LOCK_TTL_S || mtime > now + 60 )); then rmdir "$lock" 2>/dev/null || true; fi
|
|
58
|
+
fi
|
|
59
|
+
# mkdir is the atomic claim: of two concurrent starts exactly one succeeds.
|
|
60
|
+
( umask 077; mkdir "$lock" ) 2>/dev/null || return 0
|
|
61
|
+
# The child gets an allowlisted environment (no inherited secrets) and stdin, stdout and
|
|
62
|
+
# stderr all on /dev/null, or the hook's pipes stay open through the child and the
|
|
63
|
+
# session waits on it.
|
|
64
|
+
local -a childenv=(env -i "PATH=${PATH:-/usr/bin:/bin}" "HOME=${HOME:-}")
|
|
65
|
+
for v in XDG_CACHE_HOME CLAUDE_PLUGIN_ROOT TMPDIR SOLEUR_FETCH_TIMEOUT \
|
|
66
|
+
SSL_CERT_FILE SSL_CERT_DIR CURL_CA_BUNDLE GIT_SSL_CAINFO \
|
|
67
|
+
http_proxy https_proxy all_proxy no_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY; do
|
|
68
|
+
[[ -n "${!v:-}" ]] && childenv+=("$v=${!v}")
|
|
69
|
+
done
|
|
70
|
+
if command -v setsid >/dev/null 2>&1; then
|
|
71
|
+
setsid nohup "${childenv[@]}" bash "$resolver" --latest --refresh </dev/null >/dev/null 2>&1 &
|
|
72
|
+
else
|
|
73
|
+
nohup "${childenv[@]}" bash "$resolver" --latest --refresh </dev/null >/dev/null 2>&1 &
|
|
74
|
+
fi
|
|
75
|
+
disown 2>/dev/null || true
|
|
76
|
+
return 0
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
main() {
|
|
80
|
+
[[ -n "${CLAUDE_PLUGIN_ROOT:-}" ]] || return 0
|
|
81
|
+
[[ -n "${CODEX_THREAD_ID:-}" || -n "${PLUGIN_ROOT:-}" ]] && return 0
|
|
82
|
+
[[ "${SOLEUR_DISABLE_VERSION_BANNER:-}" == "1" ]] && return 0
|
|
83
|
+
|
|
84
|
+
local here resolver mode="--installed"
|
|
85
|
+
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" || return 0
|
|
86
|
+
resolver="$here/../scripts/plugin-version.sh"
|
|
87
|
+
[[ -f "$resolver" ]] || return 0
|
|
88
|
+
# One resolver call per start: --cached-latest also prints the installed keys, reads the
|
|
89
|
+
# cache only and makes no network call.
|
|
90
|
+
[[ "${SOLEUR_UPDATE_CHECK:-}" == "1" ]] && mode="--cached-latest"
|
|
91
|
+
|
|
92
|
+
local k v source="" version="" commit="" cache="" cache_dir="" latest="" relation="" label=""
|
|
93
|
+
while IFS='=' read -r k v; do
|
|
94
|
+
case "$k" in
|
|
95
|
+
source) source="$v" ;; version) version="$v" ;; commit) commit="$v" ;;
|
|
96
|
+
cache) cache="$v" ;; cache_dir) cache_dir="$v" ;; latest) latest="$v" ;; relation) relation="$v" ;;
|
|
97
|
+
esac
|
|
98
|
+
done < <(bash "$resolver" "$mode" 2>/dev/null)
|
|
99
|
+
case "$source" in
|
|
100
|
+
manifest) [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || return 0; label="v$version" ;;
|
|
101
|
+
commit) [[ "$commit" =~ ^[0-9a-f]{12}$ ]] || return 0; label="commit $commit" ;;
|
|
102
|
+
checkout) [[ "$commit" =~ ^[0-9a-f]{12}$ ]] || return 0; label="commit $commit (local checkout)" ;;
|
|
103
|
+
*) return 0 ;;
|
|
104
|
+
esac
|
|
105
|
+
|
|
106
|
+
local msg="Soleur $label"
|
|
107
|
+
|
|
108
|
+
if [[ "$mode" == "--cached-latest" ]]; then
|
|
109
|
+
# A stale value is still shown below; the refresh only helps the NEXT session.
|
|
110
|
+
case "$cache" in stale|missing|corrupt) spawn_refresh "$resolver" "$cache_dir" ;; esac
|
|
111
|
+
|
|
112
|
+
if [[ "$relation" == "older" && "$latest" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
113
|
+
local warn=1
|
|
114
|
+
if [[ "$source" == "manifest" ]]; then
|
|
115
|
+
# Never warn a downgrade: re-check the order here rather than trust the cached relation alone.
|
|
116
|
+
[[ "$(bash "$resolver" --cmp "$version" "${latest#v}" 2>/dev/null)" == "older" ]] || warn=0
|
|
117
|
+
fi
|
|
118
|
+
(( warn )) && msg="$msg — newer release $latest available"
|
|
119
|
+
fi
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
printf '{"systemMessage": "%s"}\n' "$(json_escape "$msg")"
|
|
123
|
+
return 0
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
main "$@" 2>/dev/null
|
|
127
|
+
exit 0
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
[[ -n "${CODEX_THREAD_ID:-}" || -n "${PLUGIN_ROOT:-}" ]] && exit 0
|
|
5
|
+
|
|
6
|
+
# --- Sentinel Check ---
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
source "$SCRIPT_DIR/../scripts/resolve-git-root.sh" || {
|
|
9
|
+
# Not in a git repo -- skip welcome silently
|
|
10
|
+
exit 0
|
|
11
|
+
}
|
|
12
|
+
PROJECT_ROOT="$GIT_ROOT"
|
|
13
|
+
|
|
14
|
+
# The plugin's own SessionStart registration implies the plugin is installed for
|
|
15
|
+
# the user — but plugin hooks are GLOBAL, firing in every project the user opens,
|
|
16
|
+
# so registration is not a per-project scope predicate (the old
|
|
17
|
+
# `plugins/soleur`-dir guard was the #1383 fix AND the #5119 root cause: it
|
|
18
|
+
# silenced real installs while failing to scope). The dedupe lives OUTSIDE the
|
|
19
|
+
# project tree — a plugin-owned state dir keyed by the repo-hash trick
|
|
20
|
+
# emit-decision.sh uses — so no artifact lands in the user's repo at all and
|
|
21
|
+
# welcome still fires once per project on real (marketplace) installs.
|
|
22
|
+
|
|
23
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
24
|
+
repo_key="$(printf '%s' "$PROJECT_ROOT" | sha256sum | cut -c1-16)"
|
|
25
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
26
|
+
repo_key="$(printf '%s' "$PROJECT_ROOT" | shasum -a 256 | cut -c1-16)"
|
|
27
|
+
else
|
|
28
|
+
# No sha tool: fall back to a path-derived key (slashes flattened, bounded).
|
|
29
|
+
repo_key="$(printf '%s' "$PROJECT_ROOT" | tr -c '[:alnum:]' '_' | cut -c1-120)"
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
SENTINEL_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/soleur/welcomed"
|
|
33
|
+
SENTINEL_FILE="$SENTINEL_DIR/$repo_key"
|
|
34
|
+
|
|
35
|
+
[[ -f "$SENTINEL_FILE" ]] && exit 0
|
|
36
|
+
|
|
37
|
+
# --- First-Time Welcome ---
|
|
38
|
+
# Only emit when the dedupe marker lands — a welcome that cannot be remembered
|
|
39
|
+
# fires every session, which is worse than none.
|
|
40
|
+
mkdir -p "$SENTINEL_DIR" 2>/dev/null || exit 0
|
|
41
|
+
touch "$SENTINEL_FILE" 2>/dev/null || exit 0
|
|
42
|
+
|
|
43
|
+
cat <<'WELCOME_JSON'
|
|
44
|
+
{
|
|
45
|
+
"hookSpecificOutput": {
|
|
46
|
+
"hookEventName": "SessionStart",
|
|
47
|
+
"additionalContext": "Welcome to Soleur! This appears to be the first session with Soleur installed. Suggest the user run /soleur:sync to analyze their project, or /soleur:help to see all available commands."
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
WELCOME_JSON
|