@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,706 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# github-community.sh -- GitHub community data wrapper
|
|
3
|
+
#
|
|
4
|
+
# Usage: github-community.sh <command> [args]
|
|
5
|
+
# Commands:
|
|
6
|
+
# activity [days] - Recent issues, PRs, and comments
|
|
7
|
+
# contributors [days] - Active contributors in period
|
|
8
|
+
# discussions [days] - Recent discussions (if enabled)
|
|
9
|
+
# repo-stats [days] - Stars, forks, watchers, new stargazers
|
|
10
|
+
# (new_stargazers_count is null when the token cannot list
|
|
11
|
+
# stargazers: a read-only token gets 403; see stargazers_unavailable)
|
|
12
|
+
# fetch-interactions [days] - External user comments on issues/PRs
|
|
13
|
+
#
|
|
14
|
+
# Prerequisites: gh CLI authenticated
|
|
15
|
+
# Environment:
|
|
16
|
+
# SOLEUR_COLLECTOR_COMPACT=1 - print ONE line of compact JSON per command holding only
|
|
17
|
+
# the fields the community-monitor prompt reads (#9678).
|
|
18
|
+
# Unset, or any other value, leaves the output unchanged.
|
|
19
|
+
# Output: JSON to stdout
|
|
20
|
+
# Errors: Messages to stderr, exit 1
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
# Page size for every list endpoint below. check_cap compares against it, so
|
|
25
|
+
# binding both sides to one constant keeps the truncation detector from
|
|
26
|
+
# silently retiring if a URL changes.
|
|
27
|
+
readonly PER_PAGE=100
|
|
28
|
+
|
|
29
|
+
# Compact mode (#9678): the spawned agent has no file tools, so output past the Bash
|
|
30
|
+
# tool's inline limit (30,000 characters) is unreadable. Caps are deterministic;
|
|
31
|
+
# `count` fields stay exact, titles are the newest COMPACT_MAX_ITEMS per list.
|
|
32
|
+
readonly COMPACT_MAX_ITEMS=40
|
|
33
|
+
readonly COMPACT_TITLE_MAX=60
|
|
34
|
+
readonly COMPACT_BUDGET_BYTES=6000
|
|
35
|
+
|
|
36
|
+
# --- Validation ---
|
|
37
|
+
|
|
38
|
+
validate_gh() {
|
|
39
|
+
if ! command -v gh >/dev/null 2>&1; then
|
|
40
|
+
echo "Error: gh CLI is not installed." >&2
|
|
41
|
+
echo "Install: https://cli.github.com/" >&2
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if ! gh auth status >/dev/null 2>&1; then
|
|
46
|
+
echo "Error: gh CLI is not authenticated." >&2
|
|
47
|
+
echo "Run: gh auth login" >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
detect_repo() {
|
|
53
|
+
# Fast path: GITHUB_REPOSITORY is always set in GitHub Actions
|
|
54
|
+
if [[ -n "${GITHUB_REPOSITORY:-}" ]]; then
|
|
55
|
+
echo "$GITHUB_REPOSITORY"
|
|
56
|
+
return 0
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
local remote_url
|
|
60
|
+
remote_url=$(git remote get-url origin 2>/dev/null) || {
|
|
61
|
+
echo "Error: No git remote 'origin' found." >&2
|
|
62
|
+
exit 1
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Extract owner/repo from SSH or HTTPS URL
|
|
66
|
+
# Handles: https://github.com/owner/repo.git
|
|
67
|
+
# git@github.com:owner/repo.git
|
|
68
|
+
# https://x-access-token:TOKEN@github.com/owner/repo.git
|
|
69
|
+
local repo
|
|
70
|
+
repo=$(echo "$remote_url" | sed -E 's#https?://([^@]+@)?github\.com/##' | sed -E 's#git@github\.com:##' | sed 's/\.git$//')
|
|
71
|
+
|
|
72
|
+
if [[ -z "$repo" || "$repo" == "$remote_url" ]]; then
|
|
73
|
+
echo "Error: Could not parse GitHub repo from remote URL: ${remote_url}" >&2
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo "$repo"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
date_n_days_ago() {
|
|
81
|
+
local days="${1:-7}"
|
|
82
|
+
if ! [[ "$days" =~ ^[0-9]+$ ]]; then
|
|
83
|
+
echo "Error: days must be a positive integer." >&2
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
date -u -d "${days} days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || \
|
|
87
|
+
date -u -v-"${days}"d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
check_rate_limit() {
|
|
91
|
+
local response="$1"
|
|
92
|
+
if grep -qi "rate limit" < <(jq -e '.message // empty' 2>/dev/null <<<"$response"); then
|
|
93
|
+
_CAUSE="rate-limit"
|
|
94
|
+
echo "Error: GitHub API rate limit exceeded." >&2
|
|
95
|
+
echo "" >&2
|
|
96
|
+
echo "Options:" >&2
|
|
97
|
+
echo " 1. Wait and retry (resets hourly)" >&2
|
|
98
|
+
echo " 2. Check limit: gh api rate_limit" >&2
|
|
99
|
+
exit 1
|
|
100
|
+
fi
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# --- Run state, cleanup, and the collector-status sidecar ---
|
|
104
|
+
#
|
|
105
|
+
# One trap, registered once in main(), owns BOTH tempfile cleanup and the status
|
|
106
|
+
# record. Bash EXIT traps are global and singular -- a second `trap ... EXIT`
|
|
107
|
+
# REPLACES the first -- so registering one per tempfile would silently leak all
|
|
108
|
+
# but the last on every run. Files are appended to _TMPFILES in the parent
|
|
109
|
+
# scope; a helper that appended inside a command substitution would lose every
|
|
110
|
+
# entry to the subshell.
|
|
111
|
+
|
|
112
|
+
_TMPFILES=()
|
|
113
|
+
_COMMAND=""
|
|
114
|
+
_CAUSE=""
|
|
115
|
+
_CAP_WARN=""
|
|
116
|
+
_COMPACT_CAUSE=""
|
|
117
|
+
_COMPACT_OFF=0
|
|
118
|
+
|
|
119
|
+
# Appends one JSONL record per dispatch -- success AND failure -- to a path the
|
|
120
|
+
# caller supplies. This is the only failure channel that does not terminate in
|
|
121
|
+
# the spawned agent's context window: the handler reads it directly from the
|
|
122
|
+
# run's working directory, with no LLM in the path. No-op when unset, so
|
|
123
|
+
# interactive use is unchanged.
|
|
124
|
+
_record_status() { # $1=command $2=exit $3=cause
|
|
125
|
+
[[ -n "${SOLEUR_COLLECTOR_STATUS_DIR:-}" ]] || return 0
|
|
126
|
+
mkdir -p "$SOLEUR_COLLECTOR_STATUS_DIR" 2>/dev/null || return 0
|
|
127
|
+
jq -nc \
|
|
128
|
+
--arg c "$1" \
|
|
129
|
+
--argjson e "$2" \
|
|
130
|
+
--arg r "${3:-}" \
|
|
131
|
+
--arg w "${_CAP_WARN:-}" \
|
|
132
|
+
'{collector: "github", command: $c, exit: $e, cause: $r}
|
|
133
|
+
+ (if $w == "" then {} else {warn: $w} end)' \
|
|
134
|
+
>>"$SOLEUR_COLLECTOR_STATUS_DIR/collector-status.jsonl" 2>/dev/null || true
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
_on_exit() {
|
|
138
|
+
local rc=$?
|
|
139
|
+
if ((${#_TMPFILES[@]} > 0)); then
|
|
140
|
+
rm -f "${_TMPFILES[@]}"
|
|
141
|
+
fi
|
|
142
|
+
# A failure after the compact projection was armed, with no earlier cause, is the projection.
|
|
143
|
+
if ((rc != 0)) && [[ -z "$_CAUSE" ]]; then _CAUSE="$_COMPACT_CAUSE"; fi
|
|
144
|
+
# Inside the cron (status dir set) but the handler flag did not reach us: say so in-surface.
|
|
145
|
+
if [[ "$_COMPACT_OFF" -eq 1 && ( -z "$_CAP_WARN" || "$_CAP_WARN" == truncated_at_per_page ) ]]; then _CAP_WARN="compact_off"; fi
|
|
146
|
+
_record_status "${_COMMAND:-unknown}" "$rc" "$_CAUSE"
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# Rejects any payload that is not a JSON array. A 404/403/410 body arrives at
|
|
150
|
+
# exit 0 and reaches jq as an object; without this the failure surfaces as an
|
|
151
|
+
# opaque "Cannot index string" from deep inside a jq program. This turns it into
|
|
152
|
+
# a named, greppable cause.
|
|
153
|
+
check_array_response() { # $1=file $2=what
|
|
154
|
+
# An empty body is NOT an empty result. The API renders "no results" as `[]`,
|
|
155
|
+
# so zero bytes means the response was lost, not that the period was quiet --
|
|
156
|
+
# and slurping an empty file yields [], which would render a plausible 0. This
|
|
157
|
+
# is the last path by which a missing fetch could still look like a quiet day.
|
|
158
|
+
if [[ ! -s "$1" ]] || [[ "$(jq -s 'length' <"$1" 2>/dev/null || echo 0)" -eq 0 ]]; then
|
|
159
|
+
_CAUSE="${2}-empty-response"
|
|
160
|
+
echo "GITHUB_COLLECTOR_CAUSE=${2} returned an empty body (expected a JSON array)" >&2
|
|
161
|
+
echo "Error: Failed to fetch ${2} (empty response)" >&2
|
|
162
|
+
exit 1
|
|
163
|
+
fi
|
|
164
|
+
if ! jq -se 'all(type == "array")' <"$1" >/dev/null 2>&1; then
|
|
165
|
+
local detail
|
|
166
|
+
detail=$(jq -rs '.[0].message? // empty' <"$1" 2>/dev/null | head -c 200)
|
|
167
|
+
_CAUSE="${2}-non-array"
|
|
168
|
+
echo "GITHUB_COLLECTOR_CAUSE=${2} returned a non-array payload: ${detail:-unparseable}" >&2
|
|
169
|
+
echo "Error: Failed to fetch ${2} (non-array response)" >&2
|
|
170
|
+
exit 1
|
|
171
|
+
fi
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
# True when the handler asked for compact output. A non-empty value other than 1 prints
|
|
175
|
+
# one fixed line (never the raw value) and leaves output unchanged.
|
|
176
|
+
compact_on() {
|
|
177
|
+
[[ "${SOLEUR_COLLECTOR_COMPACT:-}" == "1" ]] && return 0
|
|
178
|
+
if [[ -n "${SOLEUR_COLLECTOR_COMPACT:-}" ]]; then
|
|
179
|
+
echo "compact mode ignored: SOLEUR_COLLECTOR_COMPACT must be 1" >&2
|
|
180
|
+
fi
|
|
181
|
+
return 1
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# Prints a compact result. Called in the parent scope (never through a pipe), so the
|
|
185
|
+
# warn it may set reaches the EXIT trap's sidecar record.
|
|
186
|
+
emit_compact() { # $1=compact JSON
|
|
187
|
+
local bytes
|
|
188
|
+
bytes=$(printf '%s' "$1" | wc -c)
|
|
189
|
+
# Lowest priority: a truncation warn means counts may be undercounted, and
|
|
190
|
+
# stargazers_unavailable is acted on by the handler; both outrank a size note.
|
|
191
|
+
if ((bytes > COMPACT_BUDGET_BYTES)) && [[ -z "$_CAP_WARN" ]]; then
|
|
192
|
+
_CAP_WARN="compact_over_budget"
|
|
193
|
+
fi
|
|
194
|
+
# The projection succeeded: a later failure is not a projection failure.
|
|
195
|
+
_COMPACT_CAUSE=""
|
|
196
|
+
printf '%s\n' "$1"
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
_json_len() { # $1=file
|
|
200
|
+
jq -s 'add // [] | length' <"$1" 2>/dev/null || echo 0
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
# A response holding exactly per_page items is indistinguishable from a
|
|
204
|
+
# truncated one. Record it so a future growth-driven undercount is loud instead
|
|
205
|
+
# of silent. This is detection, not pagination.
|
|
206
|
+
#
|
|
207
|
+
# NOT applied to stargazers: that fetch paginates to exhaustion, so a total of
|
|
208
|
+
# exactly PER_PAGE means the set is COMPLETE, not truncated -- warning there
|
|
209
|
+
# would cry wolf on any repo sitting at exactly 100 stars.
|
|
210
|
+
#
|
|
211
|
+
# Takes a COUNT, not a file, because "a full page" only means truncation for
|
|
212
|
+
# endpoints that filter server-side. The pulls endpoint deliberately over-fetches
|
|
213
|
+
# a fixed page and filters by date afterwards, so a full raw page is its normal
|
|
214
|
+
# state -- warning on it would fire every run and train the reader to ignore the
|
|
215
|
+
# signal. For that endpoint the caller passes the post-filter count instead,
|
|
216
|
+
# where a full page really does mean the window is saturated.
|
|
217
|
+
check_cap() { # $1=count $2=what
|
|
218
|
+
if [[ "${1:-0}" -eq "$PER_PAGE" ]]; then
|
|
219
|
+
_CAP_WARN="truncated_at_per_page"
|
|
220
|
+
echo "WARN: ${2} returned exactly ${PER_PAGE} items (per_page cap) -- results may be truncated" >&2
|
|
221
|
+
fi
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
# --- Commands ---
|
|
225
|
+
|
|
226
|
+
cmd_activity() {
|
|
227
|
+
local days="${1:-7}"
|
|
228
|
+
local repo
|
|
229
|
+
repo=$(detect_repo)
|
|
230
|
+
local since
|
|
231
|
+
since=$(date_n_days_ago "$days")
|
|
232
|
+
|
|
233
|
+
# Payloads are spooled to files and read by jq through a file descriptor.
|
|
234
|
+
# Passing them as command-line bindings placed the whole body in a single
|
|
235
|
+
# execve argument, which breaches MAX_ARG_STRLEN (131,072 B PER ARGUMENT --
|
|
236
|
+
# not the 2 MB ARG_MAX total). That is why this failed on as few as 10 items:
|
|
237
|
+
# the ceiling is per-argument byte size, not item count. `printf` is a shell
|
|
238
|
+
# builtin, so spooling itself invokes no execve and has no size limit.
|
|
239
|
+
local issues_f prs_f
|
|
240
|
+
issues_f=$(mktemp)
|
|
241
|
+
_TMPFILES+=("$issues_f")
|
|
242
|
+
prs_f=$(mktemp)
|
|
243
|
+
_TMPFILES+=("$prs_f")
|
|
244
|
+
|
|
245
|
+
local issues prs
|
|
246
|
+
issues=$(gh api "repos/${repo}/issues?state=all&since=${since}&per_page=${PER_PAGE}" 2>&1) || {
|
|
247
|
+
_CAUSE="issues-fetch-failed"
|
|
248
|
+
echo "GITHUB_COLLECTOR_CAUSE=issues: $(echo "$issues" | head -c 200 | tr '\n' ' ')" >&2
|
|
249
|
+
echo "Error: Failed to fetch issues ($(echo "$issues" | head -c 200))" >&2
|
|
250
|
+
exit 1
|
|
251
|
+
}
|
|
252
|
+
check_rate_limit "$issues"
|
|
253
|
+
printf '%s' "$issues" >"$issues_f"
|
|
254
|
+
check_array_response "$issues_f" issues
|
|
255
|
+
check_cap "$(_json_len "$issues_f")" issues
|
|
256
|
+
|
|
257
|
+
prs=$(gh api "repos/${repo}/pulls?state=all&sort=updated&direction=desc&per_page=${PER_PAGE}" 2>&1) || {
|
|
258
|
+
_CAUSE="pulls-fetch-failed"
|
|
259
|
+
echo "GITHUB_COLLECTOR_CAUSE=pulls: $(echo "$prs" | head -c 200 | tr '\n' ' ')" >&2
|
|
260
|
+
echo "Error: Failed to fetch PRs ($(echo "$prs" | head -c 200))" >&2
|
|
261
|
+
exit 1
|
|
262
|
+
}
|
|
263
|
+
check_rate_limit "$prs"
|
|
264
|
+
printf '%s' "$prs" >"$prs_f"
|
|
265
|
+
check_array_response "$prs_f" pulls
|
|
266
|
+
# Post-filter count: see check_cap on why pulls is measured after the date filter.
|
|
267
|
+
check_cap "$(jq -s --arg since "$since" 'add // [] | map(select(.updated_at >= $since)) | length' <"$prs_f" 2>/dev/null || echo 0)" pulls
|
|
268
|
+
|
|
269
|
+
# The slurped binding wraps the file's contents in an array, so a single-array
|
|
270
|
+
# body reads as [[...]] and a paginated body as [[...],[...]]. `add // []`
|
|
271
|
+
# flattens both to one array, giving every binding in this file the same
|
|
272
|
+
# dereference shape. Leaving `length` applied to the wrapper while fixing only
|
|
273
|
+
# the projection is the silent failure: it emits count 1 alongside a full
|
|
274
|
+
# items array, at exit 0.
|
|
275
|
+
if compact_on; then
|
|
276
|
+
_COMPACT_CAUSE="compact-projection-failed"
|
|
277
|
+
local out
|
|
278
|
+
out=$(jq -nc \
|
|
279
|
+
--slurpfile issues "$issues_f" \
|
|
280
|
+
--slurpfile prs "$prs_f" \
|
|
281
|
+
--arg since "$since" \
|
|
282
|
+
--argjson max "$COMPACT_MAX_ITEMS" \
|
|
283
|
+
--argjson tmax "$COMPACT_TITLE_MAX" \
|
|
284
|
+
'def titles: sort_by(.updated_at) | reverse | .[:$max] | map((.title // "" | tostring | gsub("[[:cntrl:]\\p{Cf}\u2028\u2029]"; " "))[:$tmax]);
|
|
285
|
+
($issues | add // [] | map(select(.pull_request == null))) as $iss
|
|
286
|
+
| ($prs | add // [] | map(select(.updated_at >= $since))) as $pr
|
|
287
|
+
| {issues: {count: ($iss | length), titles: ($iss | titles)},
|
|
288
|
+
pull_requests: {count: ($pr | length), titles: ($pr | titles)}}')
|
|
289
|
+
emit_compact "$out"
|
|
290
|
+
return 0
|
|
291
|
+
fi
|
|
292
|
+
|
|
293
|
+
jq -n \
|
|
294
|
+
--slurpfile issues "$issues_f" \
|
|
295
|
+
--slurpfile prs "$prs_f" \
|
|
296
|
+
--arg since "$since" \
|
|
297
|
+
--arg repo "$repo" \
|
|
298
|
+
'($issues | add // [] | map(select(.pull_request == null))) as $iss
|
|
299
|
+
| ($prs | add // [] | map(select(.updated_at >= $since))) as $pr
|
|
300
|
+
| {
|
|
301
|
+
repo: $repo,
|
|
302
|
+
since: $since,
|
|
303
|
+
issues: {
|
|
304
|
+
count: ($iss | length),
|
|
305
|
+
items: [$iss[] | {number, title, state, user: .user.login, created_at, updated_at}]
|
|
306
|
+
},
|
|
307
|
+
pull_requests: {
|
|
308
|
+
count: ($pr | length),
|
|
309
|
+
items: [$pr[] | {number, title, state, user: .user.login, created_at, updated_at, merged_at}]
|
|
310
|
+
}
|
|
311
|
+
}'
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
cmd_contributors() {
|
|
315
|
+
local days="${1:-7}"
|
|
316
|
+
local repo
|
|
317
|
+
repo=$(detect_repo)
|
|
318
|
+
local since
|
|
319
|
+
since=$(date_n_days_ago "$days")
|
|
320
|
+
|
|
321
|
+
# Same per-argument ceiling as cmd_activity -- spool, then read via jq's file
|
|
322
|
+
# descriptor. Both files are registered with the single EXIT trap.
|
|
323
|
+
local commits_f issues_f
|
|
324
|
+
commits_f=$(mktemp)
|
|
325
|
+
_TMPFILES+=("$commits_f")
|
|
326
|
+
issues_f=$(mktemp)
|
|
327
|
+
_TMPFILES+=("$issues_f")
|
|
328
|
+
|
|
329
|
+
# Get contributors from recent commits
|
|
330
|
+
local commits
|
|
331
|
+
commits=$(gh api "repos/${repo}/commits?since=${since}&per_page=${PER_PAGE}" 2>&1) || {
|
|
332
|
+
_CAUSE="commits-fetch-failed"
|
|
333
|
+
echo "GITHUB_COLLECTOR_CAUSE=commits: $(echo "$commits" | head -c 200 | tr '\n' ' ')" >&2
|
|
334
|
+
echo "Error: Failed to fetch commits ($(echo "$commits" | head -c 200))" >&2
|
|
335
|
+
exit 1
|
|
336
|
+
}
|
|
337
|
+
check_rate_limit "$commits"
|
|
338
|
+
printf '%s' "$commits" >"$commits_f"
|
|
339
|
+
check_array_response "$commits_f" commits
|
|
340
|
+
check_cap "$(_json_len "$commits_f")" commits
|
|
341
|
+
|
|
342
|
+
# Compact mode reads only the commit total: the issues fetch below would add a call (and a
|
|
343
|
+
# failure surface) for a field the compact line never carries.
|
|
344
|
+
if compact_on; then
|
|
345
|
+
_COMPACT_CAUSE="compact-projection-failed"
|
|
346
|
+
local out
|
|
347
|
+
out=$(jq -nc --slurpfile commits "$commits_f" \
|
|
348
|
+
'{commit_total: ([($commits | add // [])[] | .author.login // .commit.author.name | select(. != null)] | length)}')
|
|
349
|
+
emit_compact "$out"
|
|
350
|
+
return 0
|
|
351
|
+
fi
|
|
352
|
+
|
|
353
|
+
# Get contributors from recent issues/PRs
|
|
354
|
+
local issues
|
|
355
|
+
issues=$(gh api "repos/${repo}/issues?state=all&since=${since}&per_page=${PER_PAGE}" 2>&1) || {
|
|
356
|
+
_CAUSE="issues-fetch-failed"
|
|
357
|
+
echo "GITHUB_COLLECTOR_CAUSE=issues: $(echo "$issues" | head -c 200 | tr '\n' ' ')" >&2
|
|
358
|
+
echo "Error: Failed to fetch issues ($(echo "$issues" | head -c 200))" >&2
|
|
359
|
+
exit 1
|
|
360
|
+
}
|
|
361
|
+
check_rate_limit "$issues"
|
|
362
|
+
printf '%s' "$issues" >"$issues_f"
|
|
363
|
+
check_array_response "$issues_f" issues
|
|
364
|
+
check_cap "$(_json_len "$issues_f")" issues
|
|
365
|
+
|
|
366
|
+
jq -n \
|
|
367
|
+
--slurpfile commits "$commits_f" \
|
|
368
|
+
--slurpfile issues "$issues_f" \
|
|
369
|
+
--arg since "$since" \
|
|
370
|
+
--arg repo "$repo" \
|
|
371
|
+
'($commits | add // []) as $cm
|
|
372
|
+
| ($issues | add // []) as $iss
|
|
373
|
+
| {
|
|
374
|
+
repo: $repo,
|
|
375
|
+
since: $since,
|
|
376
|
+
commit_authors: [
|
|
377
|
+
$cm[]
|
|
378
|
+
| .author.login // .commit.author.name
|
|
379
|
+
| select(. != null)
|
|
380
|
+
] | group_by(.) | map({login: .[0], commits: length}) | sort_by(-.commits),
|
|
381
|
+
issue_authors: [
|
|
382
|
+
$iss[]
|
|
383
|
+
| .user.login
|
|
384
|
+
| select(. != null)
|
|
385
|
+
] | group_by(.) | map({login: .[0], activity: length}) | sort_by(-.activity)
|
|
386
|
+
}'
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
cmd_discussions() {
|
|
390
|
+
local days="${1:-7}"
|
|
391
|
+
local repo
|
|
392
|
+
repo=$(detect_repo)
|
|
393
|
+
local owner repo_name
|
|
394
|
+
owner=$(echo "$repo" | cut -d/ -f1)
|
|
395
|
+
repo_name=$(echo "$repo" | cut -d/ -f2)
|
|
396
|
+
local since
|
|
397
|
+
since=$(date_n_days_ago "$days")
|
|
398
|
+
|
|
399
|
+
# Discussions require GraphQL
|
|
400
|
+
local query='query($owner: String!, $repo: String!) {
|
|
401
|
+
repository(owner: $owner, name: $repo) {
|
|
402
|
+
discussions(first: 50, orderBy: {field: UPDATED_AT, direction: DESC}) {
|
|
403
|
+
nodes {
|
|
404
|
+
number
|
|
405
|
+
title
|
|
406
|
+
author { login }
|
|
407
|
+
createdAt
|
|
408
|
+
updatedAt
|
|
409
|
+
answerChosenAt
|
|
410
|
+
comments { totalCount }
|
|
411
|
+
category { name }
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}'
|
|
416
|
+
|
|
417
|
+
local result
|
|
418
|
+
result=$(gh api graphql -f query="$query" -f owner="$owner" -f repo="$repo_name" 2>&1) || {
|
|
419
|
+
# Discussions not enabled -- return empty
|
|
420
|
+
if grep -qi "not found\|not accessible\|discussions are not enabled" <<<"$result"; then
|
|
421
|
+
if compact_on; then
|
|
422
|
+
emit_compact '{"titles":[]}'
|
|
423
|
+
return 0
|
|
424
|
+
fi
|
|
425
|
+
echo '{"discussions": [], "note": "Discussions not enabled for this repository"}'
|
|
426
|
+
return 0
|
|
427
|
+
fi
|
|
428
|
+
echo "Error: Failed to fetch discussions ($(echo "$result" | head -c 200))" >&2
|
|
429
|
+
exit 1
|
|
430
|
+
}
|
|
431
|
+
check_rate_limit "$result"
|
|
432
|
+
|
|
433
|
+
if compact_on; then
|
|
434
|
+
_COMPACT_CAUSE="compact-projection-failed"
|
|
435
|
+
local out
|
|
436
|
+
out=$(jq -c --arg since "$since" \
|
|
437
|
+
--argjson max "$COMPACT_MAX_ITEMS" \
|
|
438
|
+
--argjson tmax "$COMPACT_TITLE_MAX" \
|
|
439
|
+
'{titles: [.data.repository.discussions.nodes
|
|
440
|
+
| map(select(.updatedAt >= $since))
|
|
441
|
+
| sort_by(.updatedAt) | reverse | .[:$max][]
|
|
442
|
+
| (.title // "" | tostring | gsub("[[:cntrl:]\\p{Cf}\u2028\u2029]"; " "))[:$tmax]]}' <<<"$result")
|
|
443
|
+
emit_compact "$out"
|
|
444
|
+
return 0
|
|
445
|
+
fi
|
|
446
|
+
|
|
447
|
+
# Filter to recent discussions and format
|
|
448
|
+
echo "$result" | jq --arg since "$since" '{
|
|
449
|
+
discussions: [
|
|
450
|
+
.data.repository.discussions.nodes[]
|
|
451
|
+
| select(.updatedAt >= $since)
|
|
452
|
+
| {
|
|
453
|
+
number,
|
|
454
|
+
title,
|
|
455
|
+
author: .author.login,
|
|
456
|
+
created_at: .createdAt,
|
|
457
|
+
updated_at: .updatedAt,
|
|
458
|
+
answered: (.answerChosenAt != null),
|
|
459
|
+
comment_count: .comments.totalCount,
|
|
460
|
+
category: .category.name
|
|
461
|
+
}
|
|
462
|
+
]
|
|
463
|
+
}'
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
cmd_repo_stats() {
|
|
467
|
+
local days="${1:-7}"
|
|
468
|
+
local repo
|
|
469
|
+
repo=$(detect_repo)
|
|
470
|
+
local since
|
|
471
|
+
since=$(date_n_days_ago "$days")
|
|
472
|
+
|
|
473
|
+
# Fetch repo metadata. This body is a single repo object (~7 KB), well under
|
|
474
|
+
# the per-argument ceiling, so it stays an inline binding.
|
|
475
|
+
local repo_data
|
|
476
|
+
repo_data=$(gh api "repos/${repo}" 2>&1) || {
|
|
477
|
+
_CAUSE="repo-metadata-fetch-failed"
|
|
478
|
+
echo "GITHUB_COLLECTOR_CAUSE=repo metadata: $(echo "$repo_data" | head -c 200 | tr '\n' ' ')" >&2
|
|
479
|
+
echo "Error: Failed to fetch repo metadata ($(echo "$repo_data" | head -c 200))" >&2
|
|
480
|
+
exit 1
|
|
481
|
+
}
|
|
482
|
+
check_rate_limit "$repo_data"
|
|
483
|
+
|
|
484
|
+
# Object-shaped counterpart to check_array_response: an error body would
|
|
485
|
+
# otherwise reach the jq program and surface as an opaque indexing error.
|
|
486
|
+
if ! echo "$repo_data" | jq -e '(.stargazers_count | type) == "number"' >/dev/null 2>&1; then
|
|
487
|
+
_CAUSE="repo-metadata-non-numeric"
|
|
488
|
+
echo "GITHUB_COLLECTOR_CAUSE=repo metadata lacked a numeric stargazers_count: $(echo "$repo_data" | jq -r '.message // "unknown"' 2>/dev/null | head -c 200)" >&2
|
|
489
|
+
echo "Error: Failed to fetch repo metadata (unexpected shape)" >&2
|
|
490
|
+
exit 1
|
|
491
|
+
fi
|
|
492
|
+
|
|
493
|
+
# Fetch stargazers with timestamps (custom Accept header).
|
|
494
|
+
# stdout and stderr go to SEPARATE files. Folding the error stream into the
|
|
495
|
+
# JSON stream is what broke this parse: a single warning byte from the API
|
|
496
|
+
# client made the whole payload unparseable. Keeping them apart preserves the
|
|
497
|
+
# diagnostic without corrupting the data.
|
|
498
|
+
# --paginate emits one array per page; the slurped binding is flattened below.
|
|
499
|
+
local star_f star_err
|
|
500
|
+
star_f=$(mktemp)
|
|
501
|
+
_TMPFILES+=("$star_f")
|
|
502
|
+
star_err=$(mktemp)
|
|
503
|
+
_TMPFILES+=("$star_err")
|
|
504
|
+
|
|
505
|
+
# A READ-scoped installation token cannot list stargazers: GitHub answers 403
|
|
506
|
+
# "Resource not accessible by integration" unless the token carries contents:write
|
|
507
|
+
# (measured 2026-10-06 against REST and GraphQL; no read-level permission unlocks
|
|
508
|
+
# it). The cron spawns this script with a read-only token on purpose, so that
|
|
509
|
+
# response is the token's known limit and not a collector fault: the count is
|
|
510
|
+
# reported as null (unavailable) while everything else in repo-stats stays valid.
|
|
511
|
+
# Any other failure is still a hard failure.
|
|
512
|
+
local star_unavailable=0
|
|
513
|
+
if ! gh api "repos/${repo}/stargazers?per_page=${PER_PAGE}" \
|
|
514
|
+
-H "Accept: application/vnd.github.star+json" \
|
|
515
|
+
--paginate >"$star_f" 2>"$star_err"; then
|
|
516
|
+
# Both conjuncts: the message alone also appears behind other statuses, and a bare 403
|
|
517
|
+
# is also what a rate limit or SSO block prints. gh prints
|
|
518
|
+
# `gh: Resource not accessible by integration (HTTP 403)` on stderr (measured).
|
|
519
|
+
if grep -qi 'Resource not accessible by integration' "$star_err" && grep -q 'HTTP 403' "$star_err"; then
|
|
520
|
+
star_unavailable=1
|
|
521
|
+
# Recorded in the sidecar so the HANDLER knows without trusting the model: it forces
|
|
522
|
+
# the github row to partial/auth while this warn is present (cron-community-monitor.ts).
|
|
523
|
+
_CAP_WARN="stargazers_unavailable"
|
|
524
|
+
echo '[]' >"$star_f"
|
|
525
|
+
echo "WARN: stargazers are not readable with this token; new_stargazers_count is null" >&2
|
|
526
|
+
else
|
|
527
|
+
_CAUSE="stargazers-fetch-failed"
|
|
528
|
+
echo "GITHUB_COLLECTOR_CAUSE=stargazers: $(head -c 200 "$star_err" | tr '\n' ' ')" >&2
|
|
529
|
+
echo "Error: Failed to fetch stargazers" >&2
|
|
530
|
+
exit 1
|
|
531
|
+
fi
|
|
532
|
+
fi
|
|
533
|
+
check_array_response "$star_f" stargazers
|
|
534
|
+
|
|
535
|
+
if compact_on; then
|
|
536
|
+
_COMPACT_CAUSE="compact-projection-failed"
|
|
537
|
+
local out
|
|
538
|
+
out=$(jq -nc \
|
|
539
|
+
--argjson repo_data "$repo_data" \
|
|
540
|
+
--slurpfile stargazers "$star_f" \
|
|
541
|
+
--arg since "$since" \
|
|
542
|
+
--argjson unavailable "$star_unavailable" \
|
|
543
|
+
'def num: if type == "number" then . else error("compact: numeric field missing") end;
|
|
544
|
+
(($stargazers | add // []) | map(select(.starred_at >= $since)) | length) as $new
|
|
545
|
+
| {
|
|
546
|
+
stargazers_count: ($repo_data.stargazers_count | num),
|
|
547
|
+
forks_count: ($repo_data.forks_count | num),
|
|
548
|
+
subscribers_count: ($repo_data.subscribers_count | num),
|
|
549
|
+
new_stargazers_count: (if $unavailable == 1 then null else $new end),
|
|
550
|
+
stargazers_unavailable: ($unavailable == 1)
|
|
551
|
+
}')
|
|
552
|
+
emit_compact "$out"
|
|
553
|
+
return 0
|
|
554
|
+
fi
|
|
555
|
+
|
|
556
|
+
# Combine and filter
|
|
557
|
+
jq -n \
|
|
558
|
+
--argjson repo_data "$repo_data" \
|
|
559
|
+
--slurpfile stargazers "$star_f" \
|
|
560
|
+
--arg since "$since" \
|
|
561
|
+
--arg repo "$repo" \
|
|
562
|
+
--argjson days "$days" \
|
|
563
|
+
--argjson unavailable "$star_unavailable" \
|
|
564
|
+
'($stargazers | add // []) as $sg
|
|
565
|
+
| ([$sg[] | select(.starred_at >= $since) | {login: .user.login, starred_at}]) as $new
|
|
566
|
+
| {
|
|
567
|
+
repo: $repo,
|
|
568
|
+
since: $since,
|
|
569
|
+
stargazers_count: $repo_data.stargazers_count,
|
|
570
|
+
forks_count: $repo_data.forks_count,
|
|
571
|
+
watchers_count: $repo_data.watchers_count,
|
|
572
|
+
subscribers_count: $repo_data.subscribers_count,
|
|
573
|
+
new_stargazers: (if $unavailable == 1 then null else $new end),
|
|
574
|
+
new_stargazers_count: (if $unavailable == 1 then null else ($new | length) end),
|
|
575
|
+
stargazers_unavailable: ($unavailable == 1),
|
|
576
|
+
period_days: $days
|
|
577
|
+
}'
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
cmd_fetch_interactions() {
|
|
581
|
+
local days="${1:-1}"
|
|
582
|
+
local repo
|
|
583
|
+
repo=$(detect_repo)
|
|
584
|
+
local since
|
|
585
|
+
since=$(date_n_days_ago "$days")
|
|
586
|
+
|
|
587
|
+
# Fetch all issue/PR comments since cutoff (paginated).
|
|
588
|
+
# Use temp file -- paginated results can exceed shell argument limits.
|
|
589
|
+
# Registered with the single EXIT trap rather than removed by hand: the old
|
|
590
|
+
# form cleaned up only on the paths it remembered, leaking the spool on every
|
|
591
|
+
# other early exit.
|
|
592
|
+
#
|
|
593
|
+
# stdout and stderr go to separate files for the same reason as the stargazer
|
|
594
|
+
# fetch. The old form discarded stderr and collapsed the body through
|
|
595
|
+
# `add // []` BEFORE any validation, so a lost or error response became an
|
|
596
|
+
# empty interaction list at exit 0 -- a quiet day, indistinguishable from a
|
|
597
|
+
# real one.
|
|
598
|
+
local tmpfile err_f
|
|
599
|
+
tmpfile=$(mktemp)
|
|
600
|
+
_TMPFILES+=("$tmpfile")
|
|
601
|
+
err_f=$(mktemp)
|
|
602
|
+
_TMPFILES+=("$err_f")
|
|
603
|
+
|
|
604
|
+
if ! gh api "repos/${repo}/issues/comments?since=${since}&per_page=${PER_PAGE}" \
|
|
605
|
+
--paginate >"$tmpfile" 2>"$err_f"; then
|
|
606
|
+
_CAUSE="issue-comments-fetch-failed"
|
|
607
|
+
echo "GITHUB_COLLECTOR_CAUSE=issue comments: $(head -c 200 "$err_f" | tr '\n' ' ')" >&2
|
|
608
|
+
echo "Error: Failed to fetch issue comments" >&2
|
|
609
|
+
exit 1
|
|
610
|
+
fi
|
|
611
|
+
check_array_response "$tmpfile" issue-comments
|
|
612
|
+
|
|
613
|
+
if compact_on; then
|
|
614
|
+
_COMPACT_CAUSE="compact-projection-failed"
|
|
615
|
+
local out
|
|
616
|
+
# Counts computed here so no login or comment text reaches the model.
|
|
617
|
+
out=$(jq -nc --slurpfile comments "$tmpfile" \
|
|
618
|
+
'[($comments | add // [])[]
|
|
619
|
+
| select(
|
|
620
|
+
(.author_association == "NONE" or
|
|
621
|
+
.author_association == "CONTRIBUTOR" or
|
|
622
|
+
.author_association == "FIRST_TIMER" or
|
|
623
|
+
.author_association == "FIRST_TIME_CONTRIBUTOR") and
|
|
624
|
+
(.user.type != "Bot") and
|
|
625
|
+
(.user.login | test("\\[bot\\]$") | not)
|
|
626
|
+
)] as $i
|
|
627
|
+
| {external_contributors: ([$i[] | .user.login] | unique | length),
|
|
628
|
+
interactions_count: ($i | length)}')
|
|
629
|
+
emit_compact "$out"
|
|
630
|
+
return 0
|
|
631
|
+
fi
|
|
632
|
+
|
|
633
|
+
# Filter to external users only, exclude bots
|
|
634
|
+
jq -n --slurpfile comments "$tmpfile" --arg since "$since" --arg repo "$repo" \
|
|
635
|
+
'($comments | add // []) as $c
|
|
636
|
+
| {
|
|
637
|
+
repo: $repo,
|
|
638
|
+
since: $since,
|
|
639
|
+
interactions: [
|
|
640
|
+
$c[]
|
|
641
|
+
| select(
|
|
642
|
+
(.author_association == "NONE" or
|
|
643
|
+
.author_association == "CONTRIBUTOR" or
|
|
644
|
+
.author_association == "FIRST_TIMER" or
|
|
645
|
+
.author_association == "FIRST_TIME_CONTRIBUTOR") and
|
|
646
|
+
(.user.type != "Bot") and
|
|
647
|
+
(.user.login | test("\\[bot\\]$") | not)
|
|
648
|
+
)
|
|
649
|
+
| {
|
|
650
|
+
user: .user.login,
|
|
651
|
+
issue_number: (.issue_url | split("/") | last | tonumber),
|
|
652
|
+
body_snippet: (.body | gsub("\n"; " ") | .[:120]),
|
|
653
|
+
url: .html_url,
|
|
654
|
+
created_at: .created_at
|
|
655
|
+
}
|
|
656
|
+
]
|
|
657
|
+
}'
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
# --- Main ---
|
|
661
|
+
|
|
662
|
+
main() {
|
|
663
|
+
local command="${1:-}"
|
|
664
|
+
shift || true
|
|
665
|
+
|
|
666
|
+
if [[ -z "$command" ]]; then
|
|
667
|
+
echo "Usage: github-community.sh <command> [args]" >&2
|
|
668
|
+
echo "" >&2
|
|
669
|
+
echo "Commands:" >&2
|
|
670
|
+
echo " activity [days] - Recent issues, PRs, and comments" >&2
|
|
671
|
+
echo " contributors [days] - Active contributors in period" >&2
|
|
672
|
+
echo " discussions [days] - Recent discussions (if enabled)" >&2
|
|
673
|
+
echo " repo-stats [days] - Stars, forks, watchers, new stargazers" >&2
|
|
674
|
+
echo " fetch-interactions [days] - External user comments on issues/PRs" >&2
|
|
675
|
+
exit 1
|
|
676
|
+
fi
|
|
677
|
+
|
|
678
|
+
# One trap for the whole run, registered before the first thing that can
|
|
679
|
+
# fail, so cleanup and the status record cover validation failures too.
|
|
680
|
+
# EXIT, never RETURN: a RETURN trap does not fire on `exit`, which is exactly
|
|
681
|
+
# how every failure branch below terminates.
|
|
682
|
+
_COMMAND="$command"
|
|
683
|
+
trap _on_exit EXIT
|
|
684
|
+
|
|
685
|
+
# Inside the cron (status dir set) the handler is expected to have set the flag.
|
|
686
|
+
if [[ -n "${SOLEUR_COLLECTOR_STATUS_DIR:-}" && "${SOLEUR_COLLECTOR_COMPACT:-}" != "1" ]]; then
|
|
687
|
+
_COMPACT_OFF=1
|
|
688
|
+
fi
|
|
689
|
+
|
|
690
|
+
validate_gh
|
|
691
|
+
|
|
692
|
+
case "$command" in
|
|
693
|
+
activity) cmd_activity "$@" ;;
|
|
694
|
+
contributors) cmd_contributors "$@" ;;
|
|
695
|
+
discussions) cmd_discussions "$@" ;;
|
|
696
|
+
repo-stats) cmd_repo_stats "$@" ;;
|
|
697
|
+
fetch-interactions) cmd_fetch_interactions "$@" ;;
|
|
698
|
+
*)
|
|
699
|
+
echo "Error: Unknown command '${command}'" >&2
|
|
700
|
+
echo "Run 'github-community.sh' without arguments for usage." >&2
|
|
701
|
+
exit 1
|
|
702
|
+
;;
|
|
703
|
+
esac
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
main "$@"
|