@joshuafolkken/kit 1.1050.0 → 1.1094.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/settings.json +9 -8
- package/.claude/skills/epic-commands/SKILL.md +5 -7
- package/.claude/skills/workflow-commands/SKILL.md +19 -11
- package/.claude/skills/workflow-commands/background-commands.md +4 -3
- package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
- package/.claude/skills/workflow-commands/backlogrun-progress.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
- package/.claude/skills/workflow-commands/backlogrun.md +2 -2
- package/.claude/skills/workflow-commands/chain-rule.md +4 -2
- package/.claude/skills/workflow-commands/delegation.md +3 -3
- package/.claude/skills/workflow-commands/followup-reference.md +1 -1
- package/.claude/skills/workflow-commands/followup.md +7 -3
- package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/fullrun.md +3 -2
- package/.claude/skills/workflow-commands/halfrun.md +16 -19
- package/.claude/skills/workflow-commands/issue-comments.md +1 -1
- package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
- package/.claude/skills/workflow-commands/issue-scout.md +1 -1
- package/.claude/skills/workflow-commands/kickoff.md +9 -4
- package/.claude/skills/workflow-commands/latest-gate.md +1 -1
- package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
- package/.claude/skills/workflow-commands/observation-filing.md +3 -3
- package/.claude/skills/workflow-commands/prerequisite.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +36 -0
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
- package/.codex/hooks.json +16 -20
- package/.github/actions/setup-pnpm/action.yml +93 -0
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/ci.yml +26 -128
- package/.github/workflows/pr-classification.yml +5 -41
- package/.github/workflows/publish.yml +33 -38
- package/.github/workflows/sonar-qube.yml +37 -4
- package/AGENTS.md +12 -2
- package/CLAUDE.md +15 -16
- package/GEMINI.md +14 -2
- package/README.md +59 -18
- package/SECURITY.md +36 -6
- package/cspell/index.yaml +2 -1
- package/dist/CLAUDE.md +15 -16
- package/dist/config-merge/index.js +15 -3
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-HJIISEAC.js → chunk-3C4YCCEF.js} +5 -13
- package/dist/hooks/{chunk-EJDX2TOB.js → chunk-7ZPFAVR7.js} +7 -88
- package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-E54KGFEQ.js} +2 -2
- package/dist/hooks/{chunk-GQ7KP45M.js → chunk-IL27YTPH.js} +2 -2
- package/dist/hooks/{chunk-DMQN45FN.js → chunk-KHWHKJOM.js} +3 -3
- package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M2XDCUKD.js} +997 -478
- package/dist/hooks/{chunk-7VPDUBRN.js → chunk-NKOG3XAV.js} +150 -153
- package/dist/hooks/{chunk-NJQOBE6L.js → chunk-O4LL4HTI.js} +2 -7
- package/dist/hooks/{chunk-NAS4C7GP.js → chunk-OIZUHPJI.js} +2 -2
- package/dist/hooks/{chunk-RLDX5SOC.js → chunk-UD24EAIL.js} +2084 -1412
- package/dist/hooks/codex-hook-adapter.js +10 -11
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +279 -0
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/session-lang.js +0 -1
- package/dist/hooks/stop-guard.js +178 -324
- package/dist/josh.js +162 -119
- package/dist/managed-marker/index.js +2 -1
- package/dist/version/index.js +34 -58
- package/eslint/rules/promise.js +5 -0
- package/package.json +9 -4
- package/prompts/collaboration-workflow/issue-citation.md +5 -5
- package/prompts/collaboration-workflow/operating-rules.md +4 -4
- package/prompts/collaboration-workflow/overview.md +13 -1
- package/prompts/collaboration-workflow/report-format.md +1 -1
- package/prompts/collaboration-workflow/residency.md +3 -3
- package/prompts/collaboration-workflow/rule-delivery.md +1 -1
- package/prompts/collaboration-workflow/turn-batching.md +3 -3
- package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
- package/prompts/collaboration-workflow/wip-cap.md +25 -22
- package/prompts/collaboration-workflow.md +5 -8
- package/prompts/review-rubric.md +1 -1
- package/prompts/review.md +3 -3
- package/prompts/sonar-hotspot-handling.md +11 -3
- package/prompts/testing-guide.md +3 -3
- package/scripts/adopt/adopt-toolkits.ts +0 -2
- package/scripts/adopt/adopt.ts +0 -2
- package/scripts/agent/agent-argv.ts +0 -2
- package/scripts/agent/agent-diagnostics.ts +1 -1
- package/scripts/agent/agent-role-profile.ts +0 -7
- package/scripts/agent/claude-agent-argv.ts +0 -2
- package/scripts/agent/codex-agent-argv.ts +1 -1
- package/scripts/agent/codex-hooks.ts +92 -0
- package/scripts/agent/interactive-ask.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +6 -16
- package/scripts/backlog/backlog-budget.ts +0 -2
- package/scripts/backlog/backlog-defect-priority.ts +2 -2
- package/scripts/backlog/backlog-drive-cli.ts +10 -8
- package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
- package/scripts/backlog/backlog-drive-named.ts +2 -1
- package/scripts/backlog/backlog-drive.ts +76 -16
- package/scripts/backlog/backlog-named.ts +0 -3
- package/scripts/backlog/backlog-next.ts +9 -15
- package/scripts/backlog/backlog-offer-cli.ts +0 -5
- package/scripts/backlog/backlog-plan-cli.ts +1 -7
- package/scripts/backlog/backlog-plan.ts +1 -1
- package/scripts/backlog/backlog-pool.ts +3 -6
- package/scripts/backlog/backlog-rank.ts +2 -2
- package/scripts/backlog/backlog-ready.ts +19 -3
- package/scripts/backlog/backlog-scope.ts +1 -3
- package/scripts/backlog/backlog-stalled-detect.ts +2 -2
- package/scripts/backlog/backlog-stalled.ts +0 -1
- package/scripts/backlog/backlog-waves.ts +5 -2
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/build/build-codex-hooks.ts +26 -0
- package/scripts/build/build-hooks.ts +85 -9
- package/scripts/build/hook-bundle-stamp.ts +111 -0
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +1 -1
- package/scripts/ci/composite-actions.ts +30 -0
- package/scripts/ci/pr-classification.ts +3 -3
- package/scripts/claude/workflow-destination.ts +10 -1
- package/scripts/clone/clone-fingerprint.ts +0 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/json-format.ts +0 -1
- package/scripts/config-merge/patch-yaml-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +2 -9
- package/scripts/cost-runtime/cost-attribute.ts +0 -1
- package/scripts/cost-runtime/cost-cli.ts +0 -3
- package/scripts/cost-runtime/cost-corpus.ts +0 -2
- package/scripts/cost-runtime/cost-format.ts +0 -3
- package/scripts/cost-runtime/cost-pricing.ts +0 -1
- package/scripts/cost-runtime/cost-tokens.ts +0 -1
- package/scripts/delegation/delegation-cli.ts +1 -1
- package/scripts/delegation/delegation-policy.ts +0 -1
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +0 -2
- package/scripts/delegation/investigation-reads.ts +1 -164
- package/scripts/discovery/repo-map-logic.ts +0 -1
- package/scripts/discovery/repo-party-cli.ts +1 -1
- package/scripts/doctor/doctor-consumer.ts +4 -6
- package/scripts/doctor/doctor-logic.ts +0 -4
- package/scripts/doctor/doctor.ts +14 -9
- package/scripts/document/document-byte-budget.ts +4 -5
- package/scripts/document/document-byte-check.ts +0 -1
- package/scripts/document/document-read-cli.ts +0 -2
- package/scripts/document/document-section-cli.ts +1 -1
- package/scripts/document/document-section.ts +0 -3
- package/scripts/document/edit-files-cli.ts +0 -1
- package/scripts/document/entry-read-budget.ts +10 -2
- package/scripts/document/lane-child-read-set.ts +1 -6
- package/scripts/document/read-files-cli.ts +0 -4
- package/scripts/document/read-set-cli.ts +0 -2
- package/scripts/document/read-set-point-of-use.ts +1 -0
- package/scripts/document/read-set-pricing.ts +0 -1
- package/scripts/document/read-set-trim.ts +1 -1
- package/scripts/epic/epic-add.ts +1 -1
- package/scripts/epic/epic-audit-cli.ts +1 -4
- package/scripts/epic/epic-audit-orphans.ts +1 -3
- package/scripts/epic/epic-audit-rationale.ts +0 -1
- package/scripts/epic/epic-audit-report.ts +0 -2
- package/scripts/epic/epic-audit.ts +5 -4
- package/scripts/epic/epic-bundle-cli.ts +1 -1
- package/scripts/epic/epic-bundle-evidence.ts +0 -1
- package/scripts/epic/epic-bundle-referenced.ts +1 -5
- package/scripts/epic/epic-bundle.ts +0 -4
- package/scripts/epic/epic-busy.ts +4 -5
- package/scripts/epic/epic-candidate-confirm.ts +0 -5
- package/scripts/epic/epic-classify.ts +2 -2
- package/scripts/epic/epic-cli-argv.ts +0 -1
- package/scripts/epic/epic-close-comment.ts +1 -1
- package/scripts/epic/epic-close.ts +5 -2
- package/scripts/epic/epic-cross-repo.ts +2 -4
- package/scripts/epic/epic-decision.ts +0 -1
- package/scripts/epic/epic-fetch.ts +2 -2
- package/scripts/epic/epic-index.ts +2 -3
- package/scripts/epic/epic-issue.ts +1 -15
- package/scripts/epic/epic-lane-offer.ts +9 -8
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +1 -3
- package/scripts/epic/epic-next-views.ts +0 -1
- package/scripts/epic/epic-next.ts +1 -10
- package/scripts/epic/epic-parse.ts +0 -1
- package/scripts/epic/epic-promote.ts +0 -9
- package/scripts/epic/epic-rank.ts +2 -2
- package/scripts/epic/epic-read.ts +1 -2
- package/scripts/epic/epic-reconcile.ts +1 -1
- package/scripts/epic/epic-reference.ts +1 -13
- package/scripts/epic/epic-relation-recheck.ts +1 -1
- package/scripts/epic/epic-relations.ts +1 -1
- package/scripts/epic/epic-remove.ts +1 -1
- package/scripts/epic/epic-report.ts +0 -1
- package/scripts/epic/epic-run.ts +2 -3
- package/scripts/epic/epic-shape.ts +1 -1
- package/scripts/epic/epic-solo-stale.ts +107 -0
- package/scripts/epic/epic-solo.ts +3 -2
- package/scripts/epic/epic-triage.ts +1 -1
- package/scripts/epic/epic-validate.ts +1 -1
- package/scripts/epic/epic.ts +1 -1
- package/scripts/exports/unused-members-cli.ts +53 -0
- package/scripts/{git → followup}/followup-issue-number.ts +1 -6
- package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
- package/scripts/{git → followup}/git-followup-finish.ts +1 -3
- package/scripts/{git → followup}/git-followup-flush.ts +2 -2
- package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
- package/scripts/{git → followup}/git-followup-label.ts +4 -4
- package/scripts/followup/git-followup-merged.ts +112 -0
- package/scripts/{git → followup}/git-followup-pending.ts +1 -1
- package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
- package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
- package/scripts/{git → followup}/git-pr-followup.ts +53 -16
- package/scripts/gate/core-budget.ts +3 -9
- package/scripts/gate/gate-plan.ts +7 -4
- package/scripts/gate/gate-report.ts +0 -6
- package/scripts/gate/gate-tree.ts +1 -1
- package/scripts/gate/pre-commit-type-check.ts +0 -6
- package/scripts/gate/project-checks.ts +7 -8
- package/scripts/gate/scoped-green.ts +0 -1
- package/scripts/gate/type-check-step.ts +1 -1
- package/scripts/gate/verification-gate.ts +0 -2
- package/scripts/gh/fix-gh-packages.ts +15 -12
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
- package/scripts/{git → gh}/git-gh-check.ts +2 -1
- package/scripts/{git → gh}/git-gh-exec.ts +1 -1
- package/scripts/{git → gh}/git-gh-failure.ts +1 -1
- package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
- package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
- package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
- package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
- package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
- package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
- package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
- package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
- package/scripts/{git → gh}/git-gh-pr.ts +3 -1
- package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
- package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
- package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
- package/scripts/{git → gh}/git-pr-checks.ts +2 -1
- package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
- package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
- package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
- package/scripts/{git → gh}/git-pr.ts +3 -3
- package/scripts/git/changed-file-scope.ts +0 -1
- package/scripts/git/git-branch.ts +3 -6
- package/scripts/git/git-commit.ts +1 -1
- package/scripts/git/git-common-directory.ts +80 -24
- package/scripts/git/git-error.ts +66 -9
- package/scripts/git/git-issue.ts +1 -1
- package/scripts/git/git-preflight.ts +2 -2
- package/scripts/git/git-prompt.ts +6 -31
- package/scripts/git/git-push.ts +1 -1
- package/scripts/git/git-staging.ts +1 -0
- package/scripts/git/git-status.ts +1 -1
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/gone-branch.ts +1 -0
- package/scripts/git/listing-cutoff.ts +1 -1
- package/scripts/git/main-merge.ts +1 -1
- package/scripts/git/main-sync.ts +19 -1
- package/scripts/git/parse-json-array.ts +0 -3
- package/scripts/git/repository-lock.ts +16 -16
- package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
- package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
- package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
- package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
- package/scripts/hooks/codex-hook-adapter.ts +0 -1
- package/scripts/hooks/edited-cspell.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +2 -0
- package/scripts/hooks/pre-push-unit.ts +0 -4
- package/scripts/hooks/pretool-guard.ts +22 -4
- package/scripts/hooks/reserved-run.ts +1 -1
- package/scripts/hooks/step-zero-notice.ts +76 -0
- package/scripts/hooks/stop-guard.ts +47 -21
- package/scripts/init/claude-plugin-config.ts +4 -5
- package/scripts/init/hook-command-rewrite.ts +16 -8
- package/scripts/init/hook-launch.ts +41 -15
- package/scripts/init/init-basic.ts +2 -5
- package/scripts/init/init-logic.ts +7 -0
- package/scripts/init/init.ts +0 -3
- package/scripts/init/project-profile.ts +6 -11
- package/scripts/init/start-exec.ts +1 -1
- package/scripts/init/start-setup-pr.ts +6 -6
- package/scripts/init/start-steps.ts +1 -0
- package/scripts/issue/behavior-change-lint.ts +0 -1
- package/scripts/issue/defect-rate-cli.ts +3 -3
- package/scripts/issue/defect-rate.ts +1 -2
- package/scripts/{git → issue}/git-next-issues.ts +3 -3
- package/scripts/issue/issue-backlinks-cli.ts +1 -5
- package/scripts/issue/issue-cite-cli.ts +2 -6
- package/scripts/issue/issue-cite.ts +0 -2
- package/scripts/issue/issue-classification.ts +1 -9
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +2 -2
- package/scripts/issue/issue-file-cli.ts +5 -5
- package/scripts/issue/issue-file.ts +2 -2
- package/scripts/issue/issue-fold-cli.ts +1 -1
- package/scripts/issue/issue-fold-existing-cli.ts +1 -1
- package/scripts/{git → issue}/issue-labels.ts +8 -0
- package/scripts/issue/issue-lint-cli.ts +1 -1
- package/scripts/issue/issue-merged.ts +2 -2
- package/scripts/{git → issue}/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +8 -47
- package/scripts/issue/issue-read.ts +0 -2
- package/scripts/issue/issue-report-failures.ts +80 -0
- package/scripts/issue/issue-scout-cli.ts +1 -7
- package/scripts/issue/issue-scout-closed.ts +2 -2
- package/scripts/issue/issue-scout.ts +0 -2
- package/scripts/issue/issue-state-cli.ts +5 -46
- package/scripts/issue/issue-state.ts +1 -5
- package/scripts/issue/markdown-section.ts +1 -1
- package/scripts/issue/measure-rerun-cli.ts +1 -1
- package/scripts/issue/reproduction-measure.ts +1 -1
- package/scripts/josh/cli-body.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +0 -3
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-commands-ai.ts +9 -102
- package/scripts/josh/josh-commands-backlog.ts +5 -1
- package/scripts/josh/josh-commands-development.ts +8 -1
- package/scripts/josh/josh-commands-issue.ts +2 -2
- package/scripts/josh/josh-commands-maintenance.ts +7 -0
- package/scripts/josh/josh-commands-project.ts +6 -0
- package/scripts/josh/josh-commands-run.ts +114 -0
- package/scripts/josh/josh-commands-versioning.ts +8 -0
- package/scripts/josh/josh-commands-workflow.ts +2 -2
- package/scripts/josh/path-decision.ts +0 -3
- package/scripts/josh/process-owner.ts +16 -0
- package/scripts/josh/session-language-cli.ts +0 -1
- package/scripts/lane/lane-await.ts +3 -6
- package/scripts/lane/lane-capacity.ts +6 -3
- package/scripts/lane/lane-child-invocation.ts +20 -7
- package/scripts/lane/lane-cli.ts +1 -4
- package/scripts/lane/lane-close.ts +1 -3
- package/scripts/lane/lane-dispatch.ts +3 -4
- package/scripts/lane/lane-environment.ts +0 -9
- package/scripts/lane/lane-handoff.ts +38 -0
- package/scripts/lane/lane-launch-cli.ts +21 -11
- package/scripts/lane/lane-open.ts +0 -3
- package/scripts/lane/lane-output.ts +0 -1
- package/scripts/lane/lane-registry.ts +9 -0
- package/scripts/lane/openai-lane-ship.ts +2 -0
- package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
- package/scripts/lane/openai-lane-supervisor.ts +6 -4
- package/scripts/lane/openai-review-broker.ts +3 -0
- package/scripts/lib/bounded-pool.ts +1 -0
- package/scripts/lib/json-value.ts +5 -4
- package/scripts/lib/poll.ts +3 -1
- package/scripts/lib/timed-fetch.ts +15 -0
- package/scripts/lib/timeouts.ts +13 -0
- package/scripts/{yaml → lib}/yaml-document.ts +3 -1
- package/scripts/{bytes → lines}/bytes-command.ts +0 -2
- package/scripts/lines/lines-command.ts +0 -1
- package/scripts/lint/lint-related-scope.ts +0 -1
- package/scripts/lint/lint-related.ts +1 -1
- package/scripts/{git → notify}/telegram-notify.ts +2 -2
- package/scripts/{git → notify}/telegram-test.ts +4 -4
- package/scripts/observations/observation-ledger-home.ts +0 -1
- package/scripts/observations/observation-ledger-line.ts +0 -1
- package/scripts/observations/observation-ledger-migrate.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +3 -3
- package/scripts/observations/observations-flush.ts +2 -2
- package/scripts/overrides/lockfile-overrides.ts +1 -1
- package/scripts/overrides/overrides-logic.ts +1 -1
- package/scripts/package/package-scout-cli.ts +2 -7
- package/scripts/package/package-scout.ts +0 -2
- package/scripts/propagate/propagate-git-failure.ts +0 -1
- package/scripts/propagate/propagate-git.ts +0 -2
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +0 -2
- package/scripts/propagate/propagate-steps.ts +3 -5
- package/scripts/propagate/propagate-targets.ts +0 -4
- package/scripts/propagate/propagate.ts +0 -4
- package/scripts/refactor/import-graph.ts +0 -1
- package/scripts/refactor/refactor-lint.ts +0 -2
- package/scripts/refactor/refactor-scan.ts +0 -1
- package/scripts/refactor/refactor-targets.ts +0 -1
- package/scripts/registry-migration/migrate-logic.ts +0 -2
- package/scripts/registry-migration/migrate.ts +19 -9
- package/scripts/release/github-release-cli.ts +8 -6
- package/scripts/release/github-release-environment.ts +46 -0
- package/scripts/release/github-release.ts +151 -94
- package/scripts/release/release-history.ts +0 -1
- package/scripts/release/release-plan.ts +0 -1
- package/scripts/release/release-publish.ts +2 -3
- package/scripts/release/release-scope-cli.ts +1 -2
- package/scripts/release/release-tag.ts +2 -4
- package/scripts/repo/auto-merge-setting-logic.ts +1 -4
- package/scripts/repo/repo-setting.ts +1 -1
- package/scripts/repo/repository-labels.ts +3 -3
- package/scripts/repo/required-checks-logic.ts +206 -0
- package/scripts/repo/required-checks-report.ts +71 -0
- package/scripts/repo/ruleset-check-cli.ts +53 -0
- package/scripts/repo/ruleset-check.ts +147 -0
- package/scripts/report/report-lint-cli.ts +0 -4
- package/scripts/review/disposition-cli.ts +1 -1
- package/scripts/review/live-evidence.ts +1 -1
- package/scripts/review/review-attest-cli.ts +0 -6
- package/scripts/review/review-attest.ts +4 -16
- package/scripts/review/review-brief-cli.ts +23 -6
- package/scripts/review/review-brief.ts +21 -8
- package/scripts/review/review-diff-parts.ts +89 -0
- package/scripts/review/review-diff-write.ts +97 -0
- package/scripts/review/review-finding-ledger.ts +0 -1
- package/scripts/review/review-record-cli.ts +1 -1
- package/scripts/review/review-record.ts +0 -1
- package/scripts/review/review-round2-cli.ts +1 -1
- package/scripts/review/review-stamps.ts +0 -3
- package/scripts/review/review-tree.ts +14 -2
- package/scripts/rules/decision-oracle-stage.ts +18 -0
- package/scripts/rules/decision-oracle.ts +10 -7
- package/scripts/rules/delivered-rules.ts +9 -1
- package/scripts/rules/destructive-command.ts +119 -0
- package/scripts/rules/direct-filing.ts +1 -1
- package/scripts/rules/file-body.ts +0 -3
- package/scripts/rules/filing-cap.ts +0 -2
- package/scripts/rules/gh-api.ts +7 -2
- package/scripts/rules/git-argv.ts +18 -7
- package/scripts/rules/git-force.ts +0 -2
- package/scripts/rules/implementation-cut.ts +0 -1
- package/scripts/rules/index-guard.ts +71 -0
- package/scripts/rules/issue-citation.ts +50 -25
- package/scripts/rules/lane-background.ts +15 -7
- package/scripts/rules/lane-park.ts +13 -6
- package/scripts/rules/last-prompt.ts +1 -0
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/oracle-list-cli.ts +0 -3
- package/scripts/rules/permission-guards.ts +14 -0
- package/scripts/rules/protected-files.ts +74 -0
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +0 -3
- package/scripts/rules/rule-value-cli.ts +0 -1
- package/scripts/rules/shell-body-trigger.ts +0 -1
- package/scripts/rules/shell-segments.ts +0 -1
- package/scripts/rules/stop-rules.ts +13 -5
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +0 -1
- package/scripts/rules/worktree-guard.ts +26 -9
- package/scripts/run/run-carry-cli.ts +0 -2
- package/scripts/run/run-carry-stash.ts +2 -2
- package/scripts/run/run-carry-streak.ts +1 -1
- package/scripts/run/run-cut-cli.ts +0 -7
- package/scripts/run/run-cut.ts +8 -54
- package/scripts/run/run-ending-cli.ts +1 -1
- package/scripts/run/run-ending.ts +1 -4
- package/scripts/run/run-entry-cli.ts +101 -24
- package/scripts/run/run-entry.ts +0 -1
- package/scripts/run/run-event-cli.ts +0 -2
- package/scripts/run/run-event-follow.ts +1 -0
- package/scripts/run/run-event-render.ts +1 -1
- package/scripts/run/run-event-scope.ts +53 -4
- package/scripts/run/run-event-stream.ts +0 -3
- package/scripts/run/run-event-watch.ts +1 -0
- package/scripts/run/run-halfrun-resume.ts +20 -7
- package/scripts/run/run-headless.ts +2 -2
- package/scripts/run/run-hold-cli.ts +33 -10
- package/scripts/run/run-hold.ts +25 -5
- package/scripts/run/run-issue-number.ts +1 -1
- package/scripts/run/run-liveness-cli.ts +1 -1
- package/scripts/run/run-liveness.ts +2 -3
- package/scripts/run/run-merge-cli.ts +5 -13
- package/scripts/run/run-merge-steps.ts +5 -5
- package/scripts/run/run-merge.ts +1 -1
- package/scripts/run/run-next-cli.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +0 -1
- package/scripts/run/run-preflight.ts +2 -9
- package/scripts/run/run-prep-cli.ts +2 -2
- package/scripts/run/run-prep-locate.ts +1 -1
- package/scripts/run/run-progress-cli.ts +4 -7
- package/scripts/run/run-progress-clock.ts +6 -34
- package/scripts/run/run-progress-config.ts +0 -4
- package/scripts/run/run-progress-read.ts +1 -2
- package/scripts/run/run-progress.ts +1 -2
- package/scripts/run/run-prrun-resume.ts +117 -0
- package/scripts/run/run-report-cli.ts +1 -2
- package/scripts/run/run-report.ts +0 -1
- package/scripts/run/run-retrospective.ts +1 -1
- package/scripts/run/run-review-cli.ts +0 -3
- package/scripts/run/run-review-steps.ts +2 -0
- package/scripts/run/run-review.ts +0 -2
- package/scripts/run/run-ship-cli.ts +21 -3
- package/scripts/run/run-ship-detach.ts +1 -0
- package/scripts/run/run-ship-next.ts +106 -0
- package/scripts/run/run-ship-preflight.ts +1 -1
- package/scripts/run/run-ship-return.ts +8 -3
- package/scripts/run/run-ship-review-steps.ts +18 -4
- package/scripts/run/run-ship-review.ts +11 -0
- package/scripts/run/run-ship-scoped.ts +1 -0
- package/scripts/run/run-ship-steps.ts +1 -1
- package/scripts/run/run-ship.ts +0 -1
- package/scripts/run/run-stage-read.ts +62 -0
- package/scripts/run/run-stage.ts +160 -0
- package/scripts/run/run-status-cli.ts +1 -1
- package/scripts/run/run-step-cli.ts +21 -14
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stop-notify.ts +1 -3
- package/scripts/run/run-stranded-cli.ts +0 -4
- package/scripts/run/run-stranded-detect.ts +2 -2
- package/scripts/run/run-tail-cli.ts +17 -11
- package/scripts/run/run-tail.ts +2 -0
- package/scripts/run/run-tidy-lanes.ts +2 -1
- package/scripts/run/run-tidy-stashes.ts +12 -12
- package/scripts/run/run-wake-cli.ts +2 -3
- package/scripts/run/run-wake-loop.ts +2 -2
- package/scripts/run/run-wake.ts +2 -4
- package/scripts/run/run-watcher-guard-cli.ts +0 -4
- package/scripts/run/run-watcher-guard.ts +9 -7
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/safe-chain/ci-installer-pin.ts +11 -5
- package/scripts/safe-chain/project-config.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +0 -1
- package/scripts/security/security-audit-provision.ts +3 -2
- package/scripts/security/security-audit.ts +0 -1
- package/scripts/security/security-updates-logic.ts +0 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
- package/scripts/sonar/sonar-hotspots.ts +0 -1
- package/scripts/sonar/sonar-new-code-cli.ts +150 -0
- package/scripts/sonar/sonar-new-code.ts +79 -0
- package/scripts/sonar/sonar-project.ts +97 -0
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +2 -5
- package/scripts/sync/managed-config-scope-cli.ts +1 -1
- package/scripts/sync/skill-migration.ts +0 -1
- package/scripts/sync/sync-hook-safety.ts +2 -3
- package/scripts/sync/sync.ts +1 -8
- package/scripts/sync/template-source-logic.ts +0 -1
- package/scripts/sync/workflow-pin-logic.ts +16 -28
- package/scripts/test/test-declared-logic.ts +0 -1
- package/scripts/test/test-declared.ts +0 -2
- package/scripts/test/test-red-commit.ts +2 -2
- package/scripts/test/test-red.ts +14 -7
- package/scripts/test/test-type-logic.ts +1 -1
- package/scripts/test/unit-worker-share.ts +7 -16
- package/scripts/time-runtime/time-batch-guard.ts +1 -2
- package/scripts/time-runtime/time-bundle-call.ts +0 -1
- package/scripts/time-runtime/time-bundles.ts +0 -4
- package/scripts/time-runtime/time-density-hook.ts +0 -2
- package/scripts/time-runtime/time-followup-stage.ts +1 -1
- package/scripts/time-runtime/time-format.ts +0 -73
- package/scripts/time-runtime/time-round-trips.ts +0 -4
- package/scripts/time-runtime/time-single-check.ts +1 -1
- package/scripts/time-runtime/time-spans.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +1 -2
- package/scripts/ui/ui-routes-cli.ts +0 -5
- package/scripts/ui/ui-routes.ts +0 -5
- package/scripts/version/effective-upstream.ts +2 -2
- package/scripts/version/latest-corepack.ts +7 -9
- package/scripts/version/latest-scope-cli.ts +0 -2
- package/scripts/version/latest-update.ts +0 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/publishable-range-check.ts +1 -1
- package/scripts/version/release-hold.ts +0 -4
- package/scripts/version/running-binary.ts +2 -2
- package/scripts/version/version-check-logic.ts +0 -2
- package/scripts/version/version-remote.ts +3 -3
- package/scripts/version/version-targets.ts +4 -4
- package/templates/sonar-project.properties +28 -1
- package/templates/workflows/dependabot-auto-merge.yml +5 -3
- package/templates/workflows/github-release.yml +81 -0
- package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
- package/prompts/collaboration-workflow/epic-audit.md +0 -5
- package/prompts/collaboration-workflow/epic-bundle.md +0 -5
- package/scripts/init/plugin-install-hint.ts +0 -47
- package/scripts/version/parse-json.ts +0 -13
- /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
- /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
- /package/scripts/{git → gh}/git-gh-command.ts +0 -0
- /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
- /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
- /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
- /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
- /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
- /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
- /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
- /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
- /package/scripts/{git → gh}/git-pr-error.ts +0 -0
- /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
- /package/scripts/{git → gh}/github-issue-url.ts +0 -0
- /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
- /package/scripts/{git → issue}/issue-reference.ts +0 -0
- /package/scripts/{git → lib}/animation-helpers.ts +0 -0
- /package/scripts/{git → lib}/git-animation.ts +0 -0
- /package/scripts/{git → notify}/git-notify.ts +0 -0
- /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
3
|
-
import path from 'node:path'
|
|
4
2
|
import { fileURLToPath } from 'node:url'
|
|
5
|
-
import { git_command } from '#scripts/git/git-command'
|
|
6
|
-
import { error_text } from '#scripts/lib/error-message'
|
|
7
3
|
import { managed_config_scope } from '#scripts/sync/managed-config-scope'
|
|
8
4
|
import { z } from 'zod'
|
|
9
5
|
import {
|
|
@@ -12,6 +8,7 @@ import {
|
|
|
12
8
|
type HotspotDisposition,
|
|
13
9
|
type HotspotFetch,
|
|
14
10
|
} from './sonar-hotspots'
|
|
11
|
+
import { sonar_project } from './sonar-project'
|
|
15
12
|
|
|
16
13
|
// `josh sonar:hotspots <PR>` — fetch the SonarCloud hotspots on a pull request and print the Step B
|
|
17
14
|
// disposition of each (joshuafolkken/kit#2182).
|
|
@@ -24,11 +21,7 @@ import {
|
|
|
24
21
|
|
|
25
22
|
const ARGV_OFFSET = 2
|
|
26
23
|
const USAGE = 'Usage: josh sonar:hotspots <PR>'
|
|
27
|
-
const SONAR_HOST = 'https://sonarcloud.io'
|
|
28
24
|
const HOTSPOTS_PATH = '/api/hotspots/search'
|
|
29
|
-
const PROPERTIES_FILE = 'sonar-project.properties'
|
|
30
|
-
const PROJECT_KEY_PREFIX = 'sonar.projectKey='
|
|
31
|
-
const FETCH_TIMEOUT_MS = 10_000
|
|
32
25
|
const FAILURE_EXIT_CODE = 1
|
|
33
26
|
const UNKNOWN_LINE = '?'
|
|
34
27
|
|
|
@@ -44,34 +37,17 @@ const hotspot_schema = z.looseObject({
|
|
|
44
37
|
})
|
|
45
38
|
const response_schema = z.looseObject({ hotspots: z.array(hotspot_schema).optional() })
|
|
46
39
|
|
|
47
|
-
function read_project_key(root: string): string | undefined {
|
|
48
|
-
const file = path.join(root, PROPERTIES_FILE)
|
|
49
|
-
if (!existsSync(file)) return undefined
|
|
50
|
-
|
|
51
|
-
const line = readFileSync(file, 'utf8')
|
|
52
|
-
.split('\n')
|
|
53
|
-
.find((entry) => entry.startsWith(PROJECT_KEY_PREFIX))
|
|
54
|
-
|
|
55
|
-
return line?.slice(PROJECT_KEY_PREFIX.length).trim()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
40
|
function hotspots_url(project_key: string, pull_request: string): string {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
41
|
+
return sonar_project.api_url(HOTSPOTS_PATH, {
|
|
42
|
+
projectKey: project_key,
|
|
43
|
+
pullRequest: pull_request,
|
|
44
|
+
})
|
|
62
45
|
}
|
|
63
46
|
|
|
64
47
|
async function fetch_hotspots(url: string): Promise<HotspotFetch> {
|
|
65
|
-
|
|
66
|
-
const response = await fetch(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) })
|
|
67
|
-
if (!response.ok) return { error: `HTTP ${String(response.status)}` }
|
|
68
|
-
|
|
69
|
-
const parsed = response_schema.parse(await response.json())
|
|
48
|
+
const read = await sonar_project.fetch_json(url, response_schema)
|
|
70
49
|
|
|
71
|
-
|
|
72
|
-
} catch (error) {
|
|
73
|
-
return { error: error_text.message_of(error) }
|
|
74
|
-
}
|
|
50
|
+
return 'error' in read ? read : { hotspots: read.data.hotspots ?? [] }
|
|
75
51
|
}
|
|
76
52
|
|
|
77
53
|
function is_managed(component: string): boolean {
|
|
@@ -108,23 +84,10 @@ async function fetch_and_print(project_key: string, pull_request: string): Promi
|
|
|
108
84
|
}
|
|
109
85
|
|
|
110
86
|
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
if (pull_request === undefined || pull_request.startsWith('-')) {
|
|
114
|
-
console.error(USAGE)
|
|
115
|
-
|
|
116
|
-
return FAILURE_EXIT_CODE
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const project_key = read_project_key(await git_command.repository_root())
|
|
120
|
-
|
|
121
|
-
if (project_key === undefined) {
|
|
122
|
-
console.error(`no ${PROJECT_KEY_PREFIX} found in ${PROPERTIES_FILE}`)
|
|
123
|
-
|
|
124
|
-
return FAILURE_EXIT_CODE
|
|
125
|
-
}
|
|
87
|
+
const target = await sonar_project.resolve_target(argv, USAGE)
|
|
88
|
+
if (target === undefined) return FAILURE_EXIT_CODE
|
|
126
89
|
|
|
127
|
-
await fetch_and_print(project_key, pull_request)
|
|
90
|
+
await fetch_and_print(target.project_key, target.pull_request)
|
|
128
91
|
|
|
129
92
|
return 0
|
|
130
93
|
}
|
|
@@ -136,12 +99,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
136
99
|
const sonar_hotspots_cli = {
|
|
137
100
|
fetch_hotspots,
|
|
138
101
|
format_hotspot,
|
|
139
|
-
hotspots_url,
|
|
140
|
-
is_managed,
|
|
141
|
-
main,
|
|
142
102
|
print_disposition,
|
|
143
|
-
read_project_key,
|
|
144
|
-
run,
|
|
145
103
|
USAGE,
|
|
146
104
|
}
|
|
147
105
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
import {
|
|
5
|
+
CLEAN,
|
|
6
|
+
FINDINGS,
|
|
7
|
+
sonar_new_code,
|
|
8
|
+
UNREADABLE,
|
|
9
|
+
type NewCodeFetch,
|
|
10
|
+
type NewCodeIssue,
|
|
11
|
+
type NewCodeReading,
|
|
12
|
+
} from './sonar-new-code'
|
|
13
|
+
import { sonar_project } from './sonar-project'
|
|
14
|
+
|
|
15
|
+
// `josh sonar:new-code <PR>` — fail when a pull request adds any new SonarCloud issue or duplicated
|
|
16
|
+
// block (joshuafolkken/kit#3045).
|
|
17
|
+
//
|
|
18
|
+
// `sonar-qube.yml` runs it after the scan on every pull request, so the `SonarQube` check turns red on
|
|
19
|
+
// a single finding instead of only when the Quality Gate's ratios tip over. The verdict lives in
|
|
20
|
+
// `sonar-new-code.ts`; this file is the I/O around it: two SonarCloud API reads, one line per issue,
|
|
21
|
+
// and the verdict line. A read that fails is `unreadable` and fails the check too, so an outage never
|
|
22
|
+
// passes a pull request as clean.
|
|
23
|
+
|
|
24
|
+
const ARGV_OFFSET = 2
|
|
25
|
+
const USAGE = 'Usage: josh sonar:new-code <PR>'
|
|
26
|
+
const ISSUES_PATH = '/api/issues/search'
|
|
27
|
+
const MEASURES_PATH = '/api/measures/component'
|
|
28
|
+
const DUPLICATED_BLOCKS_METRIC = 'new_duplicated_blocks'
|
|
29
|
+
// The most issues one page carries; the verdict reads the API's own total, so a longer list only
|
|
30
|
+
// shortens what is printed.
|
|
31
|
+
const ISSUE_PAGE_SIZE = '100'
|
|
32
|
+
const FAILURE_EXIT_CODE = 1
|
|
33
|
+
const UNKNOWN = '?'
|
|
34
|
+
|
|
35
|
+
// `looseObject` so a field SonarCloud adds later does not fail the parse; only the fields the report
|
|
36
|
+
// prints are declared.
|
|
37
|
+
const issue_schema = z.looseObject({
|
|
38
|
+
rule: z.string(),
|
|
39
|
+
severity: z.string().optional(),
|
|
40
|
+
type: z.string().optional(),
|
|
41
|
+
component: z.string(),
|
|
42
|
+
line: z.number().optional(),
|
|
43
|
+
message: z.string(),
|
|
44
|
+
})
|
|
45
|
+
const issues_schema = z.looseObject({ total: z.number(), issues: z.array(issue_schema) })
|
|
46
|
+
const period_schema = z.looseObject({ value: z.string().optional() })
|
|
47
|
+
const measure_schema = z.looseObject({
|
|
48
|
+
metric: z.string(),
|
|
49
|
+
value: z.string().optional(),
|
|
50
|
+
periods: z.array(period_schema).optional(),
|
|
51
|
+
})
|
|
52
|
+
const measures_schema = z.looseObject({
|
|
53
|
+
component: z.looseObject({ measures: z.array(measure_schema) }),
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
function issues_url(project_key: string, pull_request: string): string {
|
|
57
|
+
return sonar_project.api_url(ISSUES_PATH, {
|
|
58
|
+
componentKeys: project_key,
|
|
59
|
+
pullRequest: pull_request,
|
|
60
|
+
resolved: 'false',
|
|
61
|
+
ps: ISSUE_PAGE_SIZE,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function measures_url(project_key: string, pull_request: string): string {
|
|
66
|
+
return sonar_project.api_url(MEASURES_PATH, {
|
|
67
|
+
component: project_key,
|
|
68
|
+
pullRequest: pull_request,
|
|
69
|
+
metricKeys: DUPLICATED_BLOCKS_METRIC,
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function duplicated_blocks_of(measures: z.infer<typeof measures_schema>): NewCodeFetch {
|
|
74
|
+
const measure = measures.component.measures.find(
|
|
75
|
+
(entry) => entry.metric === DUPLICATED_BLOCKS_METRIC,
|
|
76
|
+
)
|
|
77
|
+
const blocks = sonar_new_code.measure_value(measure)
|
|
78
|
+
|
|
79
|
+
return blocks === undefined
|
|
80
|
+
? { error: `${DUPLICATED_BLOCKS_METRIC} is not a number` }
|
|
81
|
+
: { issues: [], issue_total: 0, duplicated_blocks: blocks }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function fetch_new_code(project_key: string, pull_request: string): Promise<NewCodeFetch> {
|
|
85
|
+
const [issues, measures] = await Promise.all([
|
|
86
|
+
sonar_project.fetch_json(issues_url(project_key, pull_request), issues_schema),
|
|
87
|
+
sonar_project.fetch_json(measures_url(project_key, pull_request), measures_schema),
|
|
88
|
+
])
|
|
89
|
+
if ('error' in issues) return { error: `issues: ${issues.error}` }
|
|
90
|
+
if ('error' in measures) return { error: `measures: ${measures.error}` }
|
|
91
|
+
|
|
92
|
+
const blocks = duplicated_blocks_of(measures.data)
|
|
93
|
+
|
|
94
|
+
return 'error' in blocks
|
|
95
|
+
? blocks
|
|
96
|
+
: { ...blocks, issues: issues.data.issues, issue_total: issues.data.total }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function format_issue(issue: NewCodeIssue): string {
|
|
100
|
+
const line = issue.line === undefined ? UNKNOWN : String(issue.line)
|
|
101
|
+
const kind = `${issue.severity ?? UNKNOWN} ${issue.type ?? UNKNOWN}`
|
|
102
|
+
|
|
103
|
+
return `${kind}\t${issue.component}:${line}\t${issue.rule}\t${issue.message}`
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function findings_line(reading: NewCodeReading): string {
|
|
107
|
+
const counts = `${String(reading.issue_total)} new issue(s), ${String(reading.duplicated_blocks)} new duplicated block(s)`
|
|
108
|
+
|
|
109
|
+
return `${FINDINGS}: ${counts} — fix them, or resolve a deliberate exception in SonarCloud`
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// The report, and whether it passes: one line per issue, then the verdict line.
|
|
113
|
+
function report(fetched: NewCodeFetch): { lines: ReadonlyArray<string>; is_clean: boolean } {
|
|
114
|
+
const verdict = sonar_new_code.verdict_of(fetched)
|
|
115
|
+
|
|
116
|
+
if ('error' in fetched) return { lines: [`${UNREADABLE}: ${fetched.error}`], is_clean: false }
|
|
117
|
+
if (verdict === CLEAN) return { lines: [CLEAN], is_clean: true }
|
|
118
|
+
|
|
119
|
+
const issue_lines = fetched.issues.map((issue) => format_issue(issue))
|
|
120
|
+
|
|
121
|
+
return { lines: [...issue_lines, findings_line(fetched)], is_clean: false }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
125
|
+
const target = await sonar_project.resolve_target(argv, USAGE)
|
|
126
|
+
if (target === undefined) return FAILURE_EXIT_CODE
|
|
127
|
+
|
|
128
|
+
const { lines, is_clean } = report(await fetch_new_code(target.project_key, target.pull_request))
|
|
129
|
+
|
|
130
|
+
for (const line of lines) console.info(line)
|
|
131
|
+
|
|
132
|
+
return is_clean ? 0 : FAILURE_EXIT_CODE
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
136
|
+
process.exitCode = await run(argv)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const sonar_new_code_cli = {
|
|
140
|
+
fetch_new_code,
|
|
141
|
+
issues_url,
|
|
142
|
+
measures_url,
|
|
143
|
+
report,
|
|
144
|
+
run,
|
|
145
|
+
USAGE,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
149
|
+
|
|
150
|
+
export { sonar_new_code_cli }
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Whether a pull request adds any new SonarCloud finding — computed from the counts rather than from
|
|
2
|
+
// the Quality Gate (joshuafolkken/kit#3045).
|
|
3
|
+
//
|
|
4
|
+
// The built-in `Sonar way` gate judges a ratio and a rating, not a count: a few MINOR code smells keep
|
|
5
|
+
// the maintainability rating at A, and a copied block in a large pull request stays under the 3%
|
|
6
|
+
// duplication threshold. So a pull request could add both and the `SonarQube` check stayed green. The
|
|
7
|
+
// verdict here is a count: one new issue of any type or severity, or one new duplicated block, is a
|
|
8
|
+
// finding. An issue resolved in SonarCloud (accepted, false positive) is not counted — the fetch asks
|
|
9
|
+
// for unresolved issues only — so that resolution stays the escape hatch for a deliberate exception.
|
|
10
|
+
|
|
11
|
+
const CLEAN = 'clean'
|
|
12
|
+
const FINDINGS = 'findings'
|
|
13
|
+
// The fetch could not be read — told apart from a clean read so a failed request never passes the
|
|
14
|
+
// check as "no findings".
|
|
15
|
+
const UNREADABLE = 'unreadable'
|
|
16
|
+
|
|
17
|
+
const NEW_CODE_VERDICTS = [CLEAN, FINDINGS, UNREADABLE] as const
|
|
18
|
+
|
|
19
|
+
type NewCodeVerdict = (typeof NEW_CODE_VERDICTS)[number]
|
|
20
|
+
|
|
21
|
+
// One issue as `api/issues/search` returns it; only the fields the report prints are declared.
|
|
22
|
+
// The optional fields carry `| undefined` explicitly so the zod-parsed shape assigns to this type
|
|
23
|
+
// under `exactOptionalPropertyTypes`.
|
|
24
|
+
interface NewCodeIssue {
|
|
25
|
+
rule: string
|
|
26
|
+
severity?: string | undefined
|
|
27
|
+
type?: string | undefined
|
|
28
|
+
component: string
|
|
29
|
+
line?: number | undefined
|
|
30
|
+
message: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// What the pull request's analysis holds: the unresolved issues (`issue_total` is the API's own count,
|
|
34
|
+
// which can exceed the page `issues` carries) and the `new_duplicated_blocks` measure.
|
|
35
|
+
interface NewCodeReading {
|
|
36
|
+
issues: ReadonlyArray<NewCodeIssue>
|
|
37
|
+
issue_total: number
|
|
38
|
+
duplicated_blocks: number
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type NewCodeFetch = NewCodeReading | { error: string }
|
|
42
|
+
|
|
43
|
+
// A measure as `api/measures/component` returns it. A `new_*` metric carries its value under
|
|
44
|
+
// `periods`; any other metric carries a top-level `value`.
|
|
45
|
+
interface SonarMeasure {
|
|
46
|
+
value?: string | undefined
|
|
47
|
+
periods?: ReadonlyArray<{ value?: string | undefined }> | undefined
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function to_count(raw: string | undefined): number | undefined {
|
|
51
|
+
if (raw === undefined) return undefined
|
|
52
|
+
|
|
53
|
+
const value = Number(raw)
|
|
54
|
+
|
|
55
|
+
return Number.isFinite(value) ? value : undefined
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The numeric value of a measure, or `undefined` when it is present but not a number. A measure the
|
|
59
|
+
// response leaves out is 0: SonarCloud omits a metric it has nothing to count on, such as a pull
|
|
60
|
+
// request that changes no analyzable file.
|
|
61
|
+
function measure_value(measure: SonarMeasure | undefined): number | undefined {
|
|
62
|
+
if (measure === undefined) return 0
|
|
63
|
+
|
|
64
|
+
return to_count(measure.periods?.[0]?.value ?? measure.value)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function verdict_of(fetch: NewCodeFetch): NewCodeVerdict {
|
|
68
|
+
if ('error' in fetch) return UNREADABLE
|
|
69
|
+
|
|
70
|
+
return fetch.issue_total > 0 || fetch.duplicated_blocks > 0 ? FINDINGS : CLEAN
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const sonar_new_code = {
|
|
74
|
+
measure_value,
|
|
75
|
+
verdict_of,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { sonar_new_code, CLEAN, FINDINGS, UNREADABLE, NEW_CODE_VERDICTS }
|
|
79
|
+
export type { NewCodeFetch, NewCodeIssue, NewCodeReading, NewCodeVerdict, SonarMeasure }
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { git_command } from '#scripts/git/git-command'
|
|
4
|
+
import { error_text } from '#scripts/lib/error-message'
|
|
5
|
+
import { timed_fetch } from '#scripts/lib/timed-fetch'
|
|
6
|
+
import type { z } from 'zod'
|
|
7
|
+
|
|
8
|
+
// The SonarCloud project a `josh sonar:*` command reads, shared by every command that calls the
|
|
9
|
+
// SonarCloud API (joshuafolkken/kit#3045): the host, the project key `sonar-project.properties`
|
|
10
|
+
// records — the file `josh init` / `josh sync` generate from the GitHub repository name — and the
|
|
11
|
+
// `<PR>` positional each command takes.
|
|
12
|
+
|
|
13
|
+
const SONAR_HOST = 'https://sonarcloud.io'
|
|
14
|
+
const PROPERTIES_FILE = 'sonar-project.properties'
|
|
15
|
+
const PROJECT_KEY_PREFIX = 'sonar.projectKey='
|
|
16
|
+
const TOKEN_VARIABLE = 'SONAR_TOKEN'
|
|
17
|
+
const AUTHORIZATION_HEADER = 'Authorization'
|
|
18
|
+
|
|
19
|
+
interface SonarTarget {
|
|
20
|
+
project_key: string
|
|
21
|
+
pull_request: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type SonarRead<T> = { data: T } | { error: string }
|
|
25
|
+
|
|
26
|
+
function read_project_key(root: string): string | undefined {
|
|
27
|
+
const file = path.join(root, PROPERTIES_FILE)
|
|
28
|
+
if (!existsSync(file)) return undefined
|
|
29
|
+
|
|
30
|
+
const line = readFileSync(file, 'utf8')
|
|
31
|
+
.split('\n')
|
|
32
|
+
.find((entry) => entry.startsWith(PROJECT_KEY_PREFIX))
|
|
33
|
+
|
|
34
|
+
return line?.slice(PROJECT_KEY_PREFIX.length).trim()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function api_url(api_path: string, query: Record<string, string>): string {
|
|
38
|
+
return `${SONAR_HOST}${api_path}?${new URLSearchParams(query).toString()}`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// A public project reads without a token; a private one needs it. CI lifts `SONAR_TOKEN` into the
|
|
42
|
+
// job env, so it is sent when present and the request is anonymous otherwise.
|
|
43
|
+
function request_init(): RequestInit {
|
|
44
|
+
const token = process.env[TOKEN_VARIABLE] ?? ''
|
|
45
|
+
|
|
46
|
+
return token === '' ? {} : { headers: [[AUTHORIZATION_HEADER, `Bearer ${token}`]] }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// One SonarCloud API read: the parsed body on success, or the reason the read failed — rate-limited,
|
|
50
|
+
// offline, a non-OK response or an unexpected shape — so a caller cannot mistake a failed read for an
|
|
51
|
+
// empty success.
|
|
52
|
+
async function fetch_json<T>(url: string, schema: z.ZodType<T>): Promise<SonarRead<T>> {
|
|
53
|
+
try {
|
|
54
|
+
const response = await timed_fetch(url, request_init())
|
|
55
|
+
if (!response.ok) return { error: `HTTP ${String(response.status)}` }
|
|
56
|
+
|
|
57
|
+
return { data: schema.parse(await response.json()) }
|
|
58
|
+
} catch (error) {
|
|
59
|
+
return { error: error_text.message_of(error) }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// The pull request named on the command line and this repository's project key, or `undefined`
|
|
64
|
+
// after printing why the command cannot run — the usage line, or the missing project key.
|
|
65
|
+
async function resolve_target(
|
|
66
|
+
argv: ReadonlyArray<string>,
|
|
67
|
+
usage: string,
|
|
68
|
+
): Promise<SonarTarget | undefined> {
|
|
69
|
+
const [pull_request] = argv
|
|
70
|
+
|
|
71
|
+
if (pull_request === undefined || pull_request.startsWith('-')) {
|
|
72
|
+
console.error(usage)
|
|
73
|
+
|
|
74
|
+
return undefined
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const project_key = read_project_key(await git_command.repository_root())
|
|
78
|
+
|
|
79
|
+
if (project_key === undefined) {
|
|
80
|
+
console.error(`no ${PROJECT_KEY_PREFIX} found in ${PROPERTIES_FILE}`)
|
|
81
|
+
|
|
82
|
+
return undefined
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { project_key, pull_request }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const sonar_project = {
|
|
89
|
+
api_url,
|
|
90
|
+
fetch_json,
|
|
91
|
+
read_project_key,
|
|
92
|
+
request_init,
|
|
93
|
+
resolve_target,
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { sonar_project }
|
|
97
|
+
export type { SonarRead, SonarTarget }
|
|
@@ -45,7 +45,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
45
45
|
process.exitCode = await run(argv)
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const split_assess_cli = {
|
|
48
|
+
const split_assess_cli = { parse_is_json }
|
|
49
49
|
|
|
50
50
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
51
51
|
|
|
@@ -27,7 +27,8 @@ interface SizeMeasurement {
|
|
|
27
27
|
verdict: SplitVerdict
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
// The guide
|
|
30
|
+
// The guide's single source: `split-assessment.md` states these once and a test pins the two equal
|
|
31
|
+
// (joshuafolkken/kit#2996). Strictly greater than: "about 10 changed files" and a change
|
|
31
32
|
// that "lands at 11 files is not thereby a split" put the bar above the round number, not at it.
|
|
32
33
|
const FILE_GUIDE = 10
|
|
33
34
|
const LINE_GUIDE = 400
|
|
@@ -112,12 +113,8 @@ const split_assess = {
|
|
|
112
113
|
SPLIT_VERDICT,
|
|
113
114
|
SINGLE_VERDICT,
|
|
114
115
|
assess,
|
|
115
|
-
measure,
|
|
116
|
-
non_test_changes,
|
|
117
116
|
parse_numstat,
|
|
118
|
-
parse_row,
|
|
119
117
|
reason,
|
|
120
|
-
verdict_for,
|
|
121
118
|
}
|
|
122
119
|
|
|
123
120
|
export type { FileChange, SizeMeasurement, SplitVerdict }
|
|
@@ -54,7 +54,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
|
54
54
|
process.exitCode = await run(argv)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
const managed_config_scope_cli = { decide, format_reason,
|
|
57
|
+
const managed_config_scope_cli = { decide, format_reason, run, USAGE }
|
|
58
58
|
|
|
59
59
|
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
60
60
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
3
4
|
import { package_version_schema } from '#scripts/lib/schemas'
|
|
4
5
|
import { KIT_PACKAGE_NAME } from '#scripts/version/kit-descriptor'
|
|
5
|
-
import { safe_json_parse } from '#scripts/version/parse-json'
|
|
6
6
|
import semver from 'semver'
|
|
7
7
|
|
|
8
8
|
// `josh sync` writes the consumer's Claude and Codex hook files, whose hooks invoke bundles under
|
|
@@ -21,7 +21,7 @@ const NODE_MODULES = 'node_modules'
|
|
|
21
21
|
function read_version_at(package_json_path: string): string | undefined {
|
|
22
22
|
if (!existsSync(package_json_path)) return undefined
|
|
23
23
|
const parsed = package_version_schema.safeParse(
|
|
24
|
-
|
|
24
|
+
json_value.parse_or_undefined(readFileSync(package_json_path, 'utf8')),
|
|
25
25
|
)
|
|
26
26
|
|
|
27
27
|
return parsed.success ? parsed.data.version : undefined
|
|
@@ -75,7 +75,6 @@ const sync_hook_safety = {
|
|
|
75
75
|
hook_write_warning,
|
|
76
76
|
installed_consumer_version,
|
|
77
77
|
is_safe_to_write_hooks,
|
|
78
|
-
outdated_install_warning,
|
|
79
78
|
read_version_at,
|
|
80
79
|
}
|
|
81
80
|
|
package/scripts/sync/sync.ts
CHANGED
|
@@ -7,7 +7,6 @@ import { gh_spawn } from '#scripts/gh/gh-spawn'
|
|
|
7
7
|
import { basic_path_migration } from '#scripts/init/basic-path-migration'
|
|
8
8
|
import { init_logic } from '#scripts/init/init-logic'
|
|
9
9
|
import { PACKAGE_DIR, PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
10
|
-
import { plugin_install_hint_module } from '#scripts/init/plugin-install-hint'
|
|
11
10
|
import { project_profile } from '#scripts/init/project-profile'
|
|
12
11
|
import { auto_merge_setting } from '#scripts/repo/auto-merge-setting'
|
|
13
12
|
import { repository_labels } from '#scripts/repo/repository-labels'
|
|
@@ -247,11 +246,6 @@ function sync_basic_artifacts(is_force: boolean): void {
|
|
|
247
246
|
sync_basic_prettier_config(path.join(PROJECT_ROOT, BASIC_PRETTIER_CONFIG))
|
|
248
247
|
}
|
|
249
248
|
|
|
250
|
-
function sync_full_artifacts(is_force: boolean): void {
|
|
251
|
-
sync_project_artifacts(is_force)
|
|
252
|
-
plugin_install_hint_module.report_plugin_install_hint()
|
|
253
|
-
}
|
|
254
|
-
|
|
255
249
|
// Checked before anything is written, never per file: the damage is the whole run, and a partial
|
|
256
250
|
// sync that stopped halfway would leave the source repository in a state neither `git checkout` nor
|
|
257
251
|
// a re-run describes (joshuafolkken/kit#868).
|
|
@@ -265,7 +259,7 @@ function main(): void {
|
|
|
265
259
|
|
|
266
260
|
console.info('\n🔄 Syncing @joshuafolkken/kit AI files\n')
|
|
267
261
|
if (project_checks.is_basic(PROJECT_ROOT)) sync_basic_artifacts(is_force)
|
|
268
|
-
else
|
|
262
|
+
else sync_project_artifacts(is_force)
|
|
269
263
|
console.info('\n✅ Done.\n')
|
|
270
264
|
}
|
|
271
265
|
|
|
@@ -278,7 +272,6 @@ const sync = {
|
|
|
278
272
|
sync_workspace_yaml: sync_ai_files.sync_workspace_yaml,
|
|
279
273
|
sync_claude_md: sync_ai_files.sync_claude_md,
|
|
280
274
|
sync_prettier_config,
|
|
281
|
-
sync_basic_prettier_config,
|
|
282
275
|
sync_playwright_config,
|
|
283
276
|
sync_deploy_vps,
|
|
284
277
|
sync_package_manager_version,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { readdirSync, readFileSync
|
|
1
|
+
import { readdirSync, readFileSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
|
+
import { composite_actions } from '#scripts/ci/composite-actions'
|
|
3
4
|
import { is_workflow_destination } from '#scripts/claude/workflow-destination'
|
|
4
5
|
import { package_path } from '#scripts/init/init-paths'
|
|
5
6
|
|
|
@@ -9,7 +10,8 @@ import { package_path } from '#scripts/init/init-paths'
|
|
|
9
10
|
//
|
|
10
11
|
// The refs committed in templates/workflows/* are NOT authoritative: every consumer
|
|
11
12
|
// workflow is written through apply_pins_for_destination, which resolves the pins from
|
|
12
|
-
// .github/workflows
|
|
13
|
+
// .github/workflows (and the composite actions under .github/actions) at write time. Dependabot
|
|
14
|
+
// only ever updates .github (its
|
|
13
15
|
// github-actions ecosystem cannot scan templates/), so a stale template ref must not be
|
|
14
16
|
// able to reach a consumer — and must not fail CI either. `josh sync-workflow-pins`
|
|
15
17
|
// stays available to refresh the committed refs, but nothing depends on it having run.
|
|
@@ -144,8 +146,19 @@ function list_workflow_sources(relative_directory: string): Array<WorkflowSource
|
|
|
144
146
|
.map((name) => read_source(relative_directory, name))
|
|
145
147
|
}
|
|
146
148
|
|
|
149
|
+
// The local composite actions are runtime sources too: `.github/actions/setup-pnpm` is the only
|
|
150
|
+
// place kit's own workflows still pin pnpm/setup (joshuafolkken/kit#2982).
|
|
151
|
+
function list_composite_action_sources(): Array<WorkflowSource> {
|
|
152
|
+
return composite_actions
|
|
153
|
+
.list(package_path)
|
|
154
|
+
.map((file) => ({ file, text: readFileSync(package_path(file), 'utf8') }))
|
|
155
|
+
}
|
|
156
|
+
|
|
147
157
|
function build_canonical_pins(): Map<string, string> {
|
|
148
|
-
return collect_canonical(
|
|
158
|
+
return collect_canonical([
|
|
159
|
+
...list_workflow_sources(RUNTIME_WORKFLOWS_DIR),
|
|
160
|
+
...list_composite_action_sources(),
|
|
161
|
+
])
|
|
149
162
|
}
|
|
150
163
|
|
|
151
164
|
// An action the templates use but .github/workflows does not: write-time injection has no
|
|
@@ -181,32 +194,10 @@ function scan_templates<T>(
|
|
|
181
194
|
return list_workflow_sources(TEMPLATE_WORKFLOWS_DIR).flatMap((source) => scan(source, canonical))
|
|
182
195
|
}
|
|
183
196
|
|
|
184
|
-
function find_pin_drift(): Array<PinDrift> {
|
|
185
|
-
return scan_templates((source, canonical) =>
|
|
186
|
-
find_drift_in_text(source.file, source.text, canonical),
|
|
187
|
-
)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
197
|
function find_unknown_template_actions(): Array<UnknownAction> {
|
|
191
198
|
return scan_templates(unknown_actions_in_source)
|
|
192
199
|
}
|
|
193
200
|
|
|
194
|
-
function write_synced(source: WorkflowSource, canonical: ReadonlyMap<string, string>): void {
|
|
195
|
-
const synced = apply_to_text(source.text, canonical)
|
|
196
|
-
if (synced !== source.text) writeFileSync(package_path(source.file), synced)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function sync_pins(): Array<PinDrift> {
|
|
200
|
-
const canonical = build_canonical_pins()
|
|
201
|
-
const drifts = find_pin_drift()
|
|
202
|
-
|
|
203
|
-
for (const source of list_workflow_sources(TEMPLATE_WORKFLOWS_DIR)) {
|
|
204
|
-
write_synced(source, canonical)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return drifts
|
|
208
|
-
}
|
|
209
|
-
|
|
210
201
|
function format_drift_message(drifts: ReadonlyArray<PinDrift>): string {
|
|
211
202
|
const lines = drifts.map(
|
|
212
203
|
(drift) =>
|
|
@@ -222,7 +213,6 @@ function format_drift_message(drifts: ReadonlyArray<PinDrift>): string {
|
|
|
222
213
|
|
|
223
214
|
const workflow_pin_logic = {
|
|
224
215
|
RUNTIME_WORKFLOWS_DIR,
|
|
225
|
-
TEMPLATE_WORKFLOWS_DIR,
|
|
226
216
|
parse_uses_line,
|
|
227
217
|
collect_canonical,
|
|
228
218
|
find_drift_in_text,
|
|
@@ -230,9 +220,7 @@ const workflow_pin_logic = {
|
|
|
230
220
|
is_workflow_destination,
|
|
231
221
|
apply_pins_for_destination,
|
|
232
222
|
build_canonical_pins,
|
|
233
|
-
find_pin_drift,
|
|
234
223
|
find_unknown_template_actions,
|
|
235
|
-
sync_pins,
|
|
236
224
|
format_drift_message,
|
|
237
225
|
}
|
|
238
226
|
|