@joshuafolkken/kit 1.1050.0 → 1.1128.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 +20 -12
- package/.claude/skills/workflow-commands/background-commands.md +36 -84
- 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 +30 -33
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -12
- 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 +8 -6
- package/.claude/skills/workflow-commands/halfrun.md +19 -21
- 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 +8 -16
- 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/pre-gate-cut.md +4 -8
- 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/split-assessment.md +4 -18
- package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
- package/.codex/hooks.json +16 -20
- package/.github/actions/setup-node/action.yml +33 -0
- package/.github/actions/setup-pnpm/action.yml +93 -0
- package/.github/dependabot.yml +5 -1
- package/.github/workflows/auto-tag.yml +2 -3
- package/.github/workflows/ci.yml +31 -134
- package/.github/workflows/dependabot-auto-merge.yml +1 -0
- package/.github/workflows/pr-classification.yml +6 -44
- package/.github/workflows/production.yml +1 -0
- package/.github/workflows/publish.yml +43 -47
- package/.github/workflows/sonar-qube.yml +41 -4
- package/.pnpmfile.mjs +29 -0
- package/AGENTS.md +5 -2
- package/CLAUDE.md +33 -27
- package/GEMINI.md +5 -2
- package/README.md +66 -20
- package/SECURITY.md +37 -6
- package/cspell/index.yaml +6 -1
- package/dist/CLAUDE.basic.md +6 -6
- package/dist/CLAUDE.md +33 -27
- package/dist/CLAUDE.static.md +6 -6
- package/dist/config-merge/index.js +48 -12
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-7VPDUBRN.js → chunk-4JZDP5X5.js} +152 -155
- package/dist/hooks/{chunk-HJIISEAC.js → chunk-5SD2YM7Z.js} +5 -13
- package/dist/hooks/{chunk-NAS4C7GP.js → chunk-77J7IEQM.js} +2 -2
- package/dist/hooks/{chunk-DMQN45FN.js → chunk-7HVB7SZG.js} +3 -3
- package/dist/hooks/{chunk-RLDX5SOC.js → chunk-AIOIOMPX.js} +4413 -1970
- package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M7QKEKWO.js} +873 -2049
- package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-MKVGBQPA.js} +2 -2
- package/dist/hooks/{chunk-EJDX2TOB.js → chunk-NXYMNPUQ.js} +7 -88
- package/dist/hooks/{chunk-NJQOBE6L.js → chunk-QVLT52OV.js} +2 -7
- package/dist/hooks/{chunk-GQ7KP45M.js → chunk-XYUIQOW3.js} +2 -2
- package/dist/hooks/codex-hook-adapter.js +12 -48
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +280 -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 +192 -333
- package/dist/josh.js +240 -148
- package/dist/managed-marker/index.js +2 -1
- package/dist/version/index.js +70 -78
- package/eslint/rules/promise.js +5 -0
- package/eslint/rules/unicorn.js +3 -2
- package/package.json +26 -5
- package/pnpm-workspace.yaml +5 -7
- package/prompts/collaboration-workflow/glossary.md +17 -0
- package/prompts/collaboration-workflow/issue-citation.md +5 -5
- package/prompts/collaboration-workflow/issue-template.md +1 -1
- package/prompts/collaboration-workflow/operating-rules.md +5 -5
- package/prompts/collaboration-workflow/overview.md +13 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- 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 +6 -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-arrival.ts +30 -10
- package/scripts/backlog/backlog-budget-cli.ts +15 -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 +6 -19
- package/scripts/backlog/backlog-plan-cli.ts +1 -7
- package/scripts/backlog/backlog-plan.ts +30 -19
- package/scripts/backlog/backlog-pool.ts +3 -6
- package/scripts/backlog/backlog-rank.ts +2 -2
- package/scripts/backlog/backlog-ready.ts +39 -10
- 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/parse-jsonc.ts +33 -3
- package/scripts/config-merge/patch-json-key.ts +13 -6
- 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 +3 -10
- 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 +6 -10
- package/scripts/doctor/doctor-io.ts +9 -13
- package/scripts/doctor/doctor-logic.ts +0 -4
- package/scripts/doctor/doctor.ts +14 -9
- package/scripts/document/backlogrun-parent-read-set.ts +12 -1
- package/scripts/document/document-byte-budget.ts +5 -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 +21 -7
- package/scripts/document/entry-read-set.ts +32 -8
- package/scripts/document/lane-child-read-set.ts +8 -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 +9 -3
- package/scripts/document/read-set-pricing.ts +0 -1
- package/scripts/document/read-set-trim.ts +4 -2
- 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 +8 -22
- 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 +13 -10
- 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-issue-write.ts +4 -1
- package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +4 -1
- 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-command.ts +6 -1
- 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-spawn-sync.ts +65 -0
- package/scripts/git/git-spawn.ts +5 -4
- 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} +2 -7
- 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-file-action.ts +54 -0
- package/scripts/init/init-logic-migrate.ts +35 -17
- package/scripts/init/init-logic-secretlint.ts +1 -1
- package/scripts/init/init-logic.ts +10 -19
- package/scripts/init/init.ts +11 -71
- package/scripts/init/kit-written-paths.ts +2 -0
- package/scripts/init/project-profile.ts +9 -17
- package/scripts/init/start-exec.ts +1 -1
- package/scripts/init/start-setup-pr.ts +6 -6
- package/scripts/init/start-steps.ts +3 -1
- package/scripts/issue/behavior-change-lint.ts +0 -1
- package/scripts/issue/defect-rate-cli.ts +64 -23
- 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-backlinks.ts +7 -14
- package/scripts/issue/issue-cite-cli.ts +2 -6
- package/scripts/issue/issue-cite.ts +12 -8
- 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 +7 -14
- 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 +21 -6
- package/scripts/issue/measure-rerun-cli.ts +74 -15
- 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 +7 -1
- 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 +3 -3
- package/scripts/josh/path-decision.ts +0 -3
- package/scripts/josh/process-owner.ts +16 -0
- package/scripts/josh/run-github-prerequisite.ts +3 -6
- package/scripts/josh/session-language-cli.ts +0 -1
- package/scripts/lane/lane-await.ts +46 -19
- 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 +5 -4
- 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 +31 -27
- 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 +7 -1
- package/scripts/lib/bounded-pool.ts +1 -0
- package/scripts/lib/cli-flags.ts +31 -2
- package/scripts/lib/error-message.ts +12 -1
- 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/line-targets.ts +0 -11
- package/scripts/lines/lines-command.ts +5 -4
- 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 +3 -10
- 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 +2 -2
- package/scripts/refactor/refactor-targets.ts +0 -1
- package/scripts/registry-migration/migrate-logic.ts +28 -21
- package/scripts/registry-migration/migrate.ts +25 -14
- package/scripts/release/github-release-cli.ts +19 -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 +38 -5
- package/scripts/release/release-scope-cli.ts +1 -2
- package/scripts/release/release-tag.ts +2 -4
- package/scripts/release/release-worktree.ts +97 -2
- 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-checkout.ts +3 -2
- 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 +10 -17
- 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/early-heartbeat.ts +4 -3
- 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 +22 -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 +20 -9
- 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-args.ts +8 -12
- 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-args.ts +1 -6
- package/scripts/run/run-cut-cli.ts +0 -7
- package/scripts/run/run-cut.ts +8 -54
- package/scripts/run/run-ending-cli.ts +2 -6
- package/scripts/run/run-ending.ts +1 -4
- package/scripts/run/run-entry-cli.ts +133 -25
- package/scripts/run/run-entry-stop.ts +104 -0
- 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-emit.ts +7 -2
- 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 +29 -6
- package/scripts/run/run-issue-number.ts +1 -1
- package/scripts/run/run-liveness-cli.ts +2 -6
- package/scripts/run/run-liveness.ts +2 -3
- package/scripts/run/run-merge-cli.ts +7 -23
- 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 +4 -2
- package/scripts/run/run-preflight.ts +2 -9
- package/scripts/run/run-prep-cli.ts +6 -3
- package/scripts/run/run-prep-locate.ts +1 -1
- package/scripts/run/run-progress-args.ts +20 -4
- package/scripts/run/run-progress-cli.ts +35 -36
- package/scripts/run/run-progress-clock.ts +10 -35
- 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 +29 -19
- 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-probe.ts +4 -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 +3 -16
- 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 +6 -2
- package/scripts/run/run-tidy-stashes.ts +12 -12
- package/scripts/run/run-wake-cli.ts +4 -13
- 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 +18 -12
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/safe-chain/ci-installer-pin.ts +11 -5
- package/scripts/safe-chain/pack-hook.ts +92 -0
- 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-ai-files.ts +4 -0
- 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-changed.ts +13 -16
- package/scripts/test/test-declared-logic.ts +0 -1
- package/scripts/test/test-declared.ts +3 -9
- 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-commands.ts +11 -1
- package/scripts/version/version-remote.ts +3 -3
- package/scripts/version/version-targets.ts +4 -4
- package/templates/CLAUDE.basic.md +6 -6
- package/templates/sonar-project.properties +28 -1
- package/templates/workflows/ci.yml +16 -82
- package/templates/workflows/dependabot-auto-merge.yml +6 -3
- package/templates/workflows/github-release.yml +79 -0
- package/tsconfig.sonar.json +4 -22
- 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.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
|
@@ -185,10 +185,11 @@ function decide(call: GuardedCall, run: GuardRun, can_record: boolean): boolean
|
|
|
185
185
|
// is the half that makes the rule believable — the promise was kept and the interval was not.
|
|
186
186
|
const EARLY_HEARTBEAT_REASON =
|
|
187
187
|
'⛔ early heartbeat: this call arms a wait timer of its own, and the progress clock is not yours ' +
|
|
188
|
-
'to keep. `pnpm josh run:progress --wait`
|
|
188
|
+
'to keep. `pnpm josh run:progress --wait` keeps it for you ' +
|
|
189
189
|
'(`JOSH_PROGRESS_INTERVAL_MINUTES`, or `josh.progress_interval_minutes` in `package.json`, ' +
|
|
190
|
-
'default 20 minutes)
|
|
191
|
-
|
|
190
|
+
'default 20 minutes): start it once in the background and it reports the five labelled lines to ' +
|
|
191
|
+
"the run's event stream on its own, without waking you — relay nothing, and start it again only " +
|
|
192
|
+
'after it exits, which it does when newly runnable work arrives. Two timers armed at ' +
|
|
192
193
|
'once is what produced reports 3–5 minutes apart on a 15-minute setting ' +
|
|
193
194
|
'(joshuafolkken/kit#1570): a new one was armed on the turn a timer fired and again on the turn a ' +
|
|
194
195
|
"child's completion woke the run, and `--mark` recorded each report without anything refusing the " +
|
package/scripts/rules/gh-api.ts
CHANGED
|
@@ -40,8 +40,13 @@ function is_gh_api(segment: string): boolean {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// A read is a `GET` — explicit via a method flag, or implicit when no field flag makes it a POST.
|
|
43
|
+
// The explicit `-X` / `--method` value, upper-cased, or `undefined` when the call names none.
|
|
44
|
+
function method_of(segment: string): string | undefined {
|
|
45
|
+
return API_METHOD.exec(segment)?.[1]?.toUpperCase()
|
|
46
|
+
}
|
|
47
|
+
|
|
43
48
|
function is_read(segment: string): boolean {
|
|
44
|
-
const method =
|
|
49
|
+
const method = method_of(segment)
|
|
45
50
|
|
|
46
51
|
if (method !== undefined) return method.toUpperCase() === READ_METHOD
|
|
47
52
|
|
|
@@ -60,6 +65,6 @@ function repo_target(segment: string): RepoTarget | undefined {
|
|
|
60
65
|
return { owner: match[OWNER_GROUP] ?? '', repo: match[REPO_GROUP] ?? '' }
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
const gh_api = {
|
|
68
|
+
const gh_api = { GH_FLAGS, is_gh_api, is_read, is_write, method_of, repo_target }
|
|
64
69
|
|
|
65
70
|
export { gh_api }
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
// arguments is what makes the judgement independent of the spelling.
|
|
13
13
|
|
|
14
14
|
// The wrapper words that may stand in front of `git`, the same ones `run-tail.ts` skips in front of
|
|
15
|
-
// `josh`: environment assignments, the package-manager launchers, `sudo`, and an opening
|
|
16
|
-
// parenthesis. Left in, `sudo git push --force` and `(git push -f)` are
|
|
15
|
+
// `josh`: environment assignments, the package-manager launchers, `sudo`, `env`, and an opening
|
|
16
|
+
// subshell parenthesis. Left in, `sudo git push --force`, `env git commit` and `(git push -f)` are
|
|
17
|
+
// silently not a git command (joshuafolkken/kit#2983).
|
|
17
18
|
const ENV_ASSIGNMENT = /^[A-Za-z_]\w*=/u
|
|
18
19
|
const WRAPPER_WORDS: ReadonlySet<string> = new Set([
|
|
19
20
|
'pnpm',
|
|
@@ -22,6 +23,7 @@ const WRAPPER_WORDS: ReadonlySet<string> = new Set([
|
|
|
22
23
|
'run',
|
|
23
24
|
'sudo',
|
|
24
25
|
'command',
|
|
26
|
+
'env',
|
|
25
27
|
])
|
|
26
28
|
const SUBSHELL_OPEN = '('
|
|
27
29
|
|
|
@@ -92,17 +94,26 @@ function after_globals(words: ReadonlyArray<string>, start: number): number {
|
|
|
92
94
|
return index
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
// The words after `command` once the wrapper is skipped, or `undefined` when the segment does not
|
|
98
|
+
// invoke it. `gh` and `rm` are judged by the same wrapper cut as `git` (joshuafolkken/kit#2983), so
|
|
99
|
+
// `env gh pr close` and `sudo rm -rf` are read as the calls they are.
|
|
100
|
+
function arguments_of(segment: string, command: string): Array<string> | undefined {
|
|
101
|
+
const words = words_of(segment)
|
|
102
|
+
const command_index = after_wrapper(words)
|
|
103
|
+
|
|
104
|
+
return words[command_index] === command ? words.slice(command_index + NEXT) : undefined
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
// The subcommand and the arguments after it, or `undefined` when the segment is not a git invocation.
|
|
96
108
|
// **`pnpm josh git` is deliberately not one**: the word after the wrapper is `josh`, not `git`, so a
|
|
97
109
|
// run's own authorized `pnpm josh git -y` push is invisible here — which is exactly what keeps this row
|
|
98
110
|
// off the node route the deny list already leaves alone.
|
|
99
111
|
function parse(segment: string): GitCall | undefined {
|
|
100
|
-
const words =
|
|
101
|
-
const git_index = after_wrapper(words)
|
|
112
|
+
const words = arguments_of(segment, GIT_COMMAND)
|
|
102
113
|
|
|
103
|
-
if (words
|
|
114
|
+
if (words === undefined) return undefined
|
|
104
115
|
|
|
105
|
-
const subcommand_index = after_globals(words,
|
|
116
|
+
const subcommand_index = after_globals(words, 0)
|
|
106
117
|
|
|
107
118
|
return { subcommand: words[subcommand_index], args: words.slice(subcommand_index + NEXT) }
|
|
108
119
|
}
|
|
@@ -124,6 +135,6 @@ function short_cluster_has(token: string, letters: string): boolean {
|
|
|
124
135
|
return false
|
|
125
136
|
}
|
|
126
137
|
|
|
127
|
-
const git_argv = { parse, short_cluster_has
|
|
138
|
+
const git_argv = { arguments_of, parse, short_cluster_has }
|
|
128
139
|
|
|
129
140
|
export { git_argv }
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { bash_triggers } from './bash-triggers'
|
|
2
|
+
import { git_argv } from './git-argv'
|
|
3
|
+
import { shell_segments } from './shell-segments'
|
|
4
|
+
import { worktree_guard } from './worktree-guard'
|
|
5
|
+
|
|
6
|
+
// The trigger and the delivered text behind the `index-mutation` row of `delivered-rules.ts`
|
|
7
|
+
// (joshuafolkken/kit#2983). `CLAUDE.md` → Git Rules forbids staging or otherwise mutating the git index
|
|
8
|
+
// on the run's own judgement, and `.claude/settings.json` backs it with `Bash(git add*)` /
|
|
9
|
+
// `Bash(git commit*)` and their siblings — but those are prefix globs, so `git -C . commit`,
|
|
10
|
+
// `git -c k=v commit` and `env git commit` all pass them. Reading the argv through `git-argv.ts`, the
|
|
11
|
+
// cut `git-force.ts` already uses, is what makes the judgement independent of the spelling.
|
|
12
|
+
//
|
|
13
|
+
// **The scope is accident prevention, not a sandbox.** Under `bypassPermissions` with `Bash(*)` a run
|
|
14
|
+
// that means to get round the guard can always do so through `python -c` or a script; the decision
|
|
15
|
+
// recorded on the Issue is to stop the variant spellings a run types by accident. The authorized
|
|
16
|
+
// commit flow is `pnpm josh git -y`, which spawns git in a child process this hook never sees.
|
|
17
|
+
//
|
|
18
|
+
// **It fires on every occurrence**, for the reason `git-force.ts` does: overwriting the user's
|
|
19
|
+
// staged snapshot is destructive each time it is issued.
|
|
20
|
+
|
|
21
|
+
// The subcommands that write the index outright. `stage` is `add`'s synonym; `rm` and `mv` stage the
|
|
22
|
+
// removal or rename they make.
|
|
23
|
+
const INDEX_SUBCOMMANDS: ReadonlySet<string> = new Set([
|
|
24
|
+
'add',
|
|
25
|
+
'commit',
|
|
26
|
+
'mv',
|
|
27
|
+
'reset',
|
|
28
|
+
'rm',
|
|
29
|
+
'stage',
|
|
30
|
+
])
|
|
31
|
+
const RESTORE_SUBCOMMAND = 'restore'
|
|
32
|
+
|
|
33
|
+
// A `git restore` that touches only the index (`--staged` / `-S` without `--worktree` / `-W`). One that
|
|
34
|
+
// touches the working tree is the `worktree-mutation` row's, so the two rows never claim one command.
|
|
35
|
+
function is_index_restore(args: ReadonlyArray<string>): boolean {
|
|
36
|
+
return !worktree_guard.touches_worktree(args)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function is_index_segment(segment: string): boolean {
|
|
40
|
+
const call = git_argv.parse(segment)
|
|
41
|
+
|
|
42
|
+
if (call === undefined) return false
|
|
43
|
+
if (INDEX_SUBCOMMANDS.has(call.subcommand ?? '')) return true
|
|
44
|
+
|
|
45
|
+
return call.subcommand === RESTORE_SUBCOMMAND && is_index_restore(call.args)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function is_index_mutation(command: string): boolean {
|
|
49
|
+
return shell_segments.segments_of(command).some((segment) => is_index_segment(segment))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const INDEX_MUTATION_REASON =
|
|
53
|
+
'⛔ git index mutation: `git add` / `stage` / `commit` / `reset` / `rm` / `mv` and `git restore ' +
|
|
54
|
+
"--staged` overwrite the user's staged snapshot, which `CLAUDE.md` → Git Rules forbids on your own " +
|
|
55
|
+
'judgement (`prompts/collaboration-workflow/operating-rules.md` → "git index を勝手に変更しない"). The ' +
|
|
56
|
+
'`.claude/settings.json` deny list matches prefix globs, so it misses `git -C . commit`, `git -c ' +
|
|
57
|
+
'k=v commit` and `env git commit`; this row reads the argv instead, so the spelling does not matter. ' +
|
|
58
|
+
'A commit goes through `pnpm josh git -y`; any other staging needs explicit current-turn user ' +
|
|
59
|
+
'instruction, run by the user in their own terminal. **This rule fires on every occurrence, not once ' +
|
|
60
|
+
'per run.**'
|
|
61
|
+
|
|
62
|
+
const ROW = {
|
|
63
|
+
id: 'index-mutation',
|
|
64
|
+
is_trigger: bash_triggers.on_bash_command(is_index_mutation),
|
|
65
|
+
reason: INDEX_MUTATION_REASON,
|
|
66
|
+
decide: (): boolean => true,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const index_guard = { INDEX_MUTATION_REASON, ROW, is_index_mutation }
|
|
70
|
+
|
|
71
|
+
export { index_guard }
|
|
@@ -34,10 +34,23 @@ const REFERENCE_BOUNDARY = /[\s#()[\]<>|]/u
|
|
|
34
34
|
// `issue:cite`'s parser accepts. A path-like run (`src/lib`, `a/b/c`) is not one, so it is not emitted
|
|
35
35
|
// as a prefix that would make the suggested `issue:cite` call refuse the very reference it names.
|
|
36
36
|
const OWNER_REPO = /^[^\s/#]+\/[^\s/#]+$/u
|
|
37
|
-
// A markdown link
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
const MARKDOWN_LINK = /\[
|
|
37
|
+
// A markdown link: `[text](target)`. Each class excludes *both* of its delimiters — no `[`/`]` in the
|
|
38
|
+
// text, no `(`/`)` in the target — so neither star is ambiguous against a nested bracket and there is
|
|
39
|
+
// nothing to backtrack.
|
|
40
|
+
const MARKDOWN_LINK = /\[[^[\]]*\]\([^()]*\)/gu
|
|
41
|
+
// What continues a `#N` into something longer, read off the two characters after its last digit: a
|
|
42
|
+
// word character (a hex color, `#1e90ff`) or a hyphen and a letter (a heading anchor, `#12-setup`) —
|
|
43
|
+
// never an Issue number (joshuafolkken/kit#2995). A hyphen before a digit or `#` is a range
|
|
44
|
+
// (`#12-#15`, `#3-5`), whose first number is still a citation.
|
|
45
|
+
const NUMBER_CONTINUATION = /^(?:\w|-[a-z])/iu
|
|
46
|
+
// The width of the window `NUMBER_CONTINUATION` reads: a hyphen and the letter after it.
|
|
47
|
+
const CONTINUATION_WIDTH = 2
|
|
48
|
+
// What, in the run of non-boundary characters before a `#N`, glues it into a longer token: the `&` of
|
|
49
|
+
// an HTML entity (`'`), the `.` of a file fragment (`README.md#12`), the `/` of a path or URL
|
|
50
|
+
// fragment (`src/lib/x#5`, `example.com/#12`). Any other lead leaves it a citation — a repository
|
|
51
|
+
// without its owner (`kit#12`), a verb (`fixes#12`), prose in a non-Latin script or emphasis
|
|
52
|
+
// (`**#12**`) is a slip all the same. A well-formed `owner/repo#N` is read off `repo_prefix` first.
|
|
53
|
+
const GLUED_LEAD = /[&./]/u
|
|
41
54
|
// A fenced-code delimiter line: three or more backticks or tildes after optional indentation — both
|
|
42
55
|
// delimiters CommonMark allows. Toggling on each one brackets the fenced block, so a `closes #N` shown
|
|
43
56
|
// in a `gh api` example never reads as a slip whichever fence the reply drew it with.
|
|
@@ -53,27 +66,34 @@ const PR_PREFIX = /\b(?:pr|pull request)\s*$/iu
|
|
|
53
66
|
// sits inside a span.
|
|
54
67
|
const BACKTICK_PAIR = 2
|
|
55
68
|
|
|
56
|
-
// Whether a markdown link
|
|
57
|
-
// `
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const start = (link.index ?? 0) + 1
|
|
61
|
-
const end = start + (link[1] ?? '').length
|
|
69
|
+
// Whether a markdown link covers `index`, text or target alike. A `#N` in the text is the approved
|
|
70
|
+
// `[#N](url)` citation; one in the target is a page fragment (`[setup](#12)`), not an Issue.
|
|
71
|
+
function link_covers(link: RegExpMatchArray, index: number): boolean {
|
|
72
|
+
const start = link.index ?? 0
|
|
62
73
|
|
|
63
|
-
return index >= start && index <
|
|
74
|
+
return index >= start && index < start + link[0].length
|
|
64
75
|
}
|
|
65
76
|
|
|
66
|
-
// The line is searched for a link
|
|
67
|
-
//
|
|
68
|
-
//
|
|
77
|
+
// The line is searched for a link covering this index, so `see [#12](url) and #34` reads the first as
|
|
78
|
+
// linked and the second as bare. The scan is line-based (`is_bare_at` passes one line), so a link and
|
|
79
|
+
// the `#N` it wraps must sit on the same line — which they always do.
|
|
69
80
|
function is_linked_at(line: string, index: number): boolean {
|
|
70
81
|
for (const link of line.matchAll(MARKDOWN_LINK)) {
|
|
71
|
-
if (
|
|
82
|
+
if (link_covers(link, index)) return true
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
return false
|
|
75
86
|
}
|
|
76
87
|
|
|
88
|
+
// The run of non-boundary characters that ends at the `#` — what `repo_prefix` keeps when it is an
|
|
89
|
+
// `owner/repo` and `is_glued` weighs when it is not.
|
|
90
|
+
function lead_token(message: string, hash_index: number): string {
|
|
91
|
+
let start = hash_index
|
|
92
|
+
while (start > 0 && !REFERENCE_BOUNDARY.test(message.charAt(start - 1))) start -= 1
|
|
93
|
+
|
|
94
|
+
return message.slice(start, hash_index)
|
|
95
|
+
}
|
|
96
|
+
|
|
77
97
|
// **The message text alone, never a GitHub-bound artifact.** An Issue body or comment is passed to
|
|
78
98
|
// `gh` as a `Bash` argument, not spoken in `last_assistant_message`, so those never reach here — which
|
|
79
99
|
// is exactly the "silent on GitHub-bound artifacts" behavior the issue asks for, obtained by what the
|
|
@@ -83,10 +103,7 @@ function is_linked_at(line: string, index: number): boolean {
|
|
|
83
103
|
// non-boundary characters ending at the `#`, kept only when it holds a `/`. Read backwards a
|
|
84
104
|
// character at a time so a repository name of any length costs its own length and no more.
|
|
85
105
|
function repo_prefix(message: string, hash_index: number): string {
|
|
86
|
-
|
|
87
|
-
while (start > 0 && !REFERENCE_BOUNDARY.test(message.charAt(start - 1))) start -= 1
|
|
88
|
-
|
|
89
|
-
const token = message.slice(start, hash_index)
|
|
106
|
+
const token = lead_token(message, hash_index)
|
|
90
107
|
|
|
91
108
|
return OWNER_REPO.test(token) ? token : ''
|
|
92
109
|
}
|
|
@@ -115,17 +132,25 @@ interface LineReference {
|
|
|
115
132
|
text: string
|
|
116
133
|
}
|
|
117
134
|
|
|
118
|
-
//
|
|
119
|
-
//
|
|
135
|
+
// Whether the `#N` is part of a longer token rather than an Issue number of its own — continued past
|
|
136
|
+
// its digits, or led by an entity, file or path run (`GLUED_LEAD`) that is not an `owner/repo`.
|
|
137
|
+
function is_glued(line: string, reference: LineReference): boolean {
|
|
138
|
+
const end = reference.index + reference.text.length
|
|
139
|
+
|
|
140
|
+
if (NUMBER_CONTINUATION.test(line.slice(end, end + CONTINUATION_WIDTH))) return true
|
|
141
|
+
|
|
142
|
+
return reference.prefix === '' && GLUED_LEAD.test(lead_token(line, reference.index))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// The bare references on one line, in order — the glued tokens (`is_glued`) and the excluded mentions
|
|
146
|
+
// (linked, inline-code, PR, `is_bare_at`) already dropped, so a caller acts on citations alone.
|
|
120
147
|
function line_references(line: string): ReadonlyArray<LineReference> {
|
|
121
148
|
const references: Array<LineReference> = []
|
|
122
149
|
|
|
123
150
|
for (const match of line.matchAll(ISSUE_NUMBER)) {
|
|
124
|
-
const { index
|
|
151
|
+
const reference = { index: match.index, prefix: repo_prefix(line, match.index), text: match[0] }
|
|
125
152
|
|
|
126
|
-
if (is_bare_at(line, index))
|
|
127
|
-
references.push({ index, prefix: repo_prefix(line, index), text: match[0] })
|
|
128
|
-
}
|
|
153
|
+
if (!is_glued(line, reference) && is_bare_at(line, match.index)) references.push(reference)
|
|
129
154
|
}
|
|
130
155
|
|
|
131
156
|
return references
|
|
@@ -20,7 +20,13 @@ import { run_tail } from './run-tail'
|
|
|
20
20
|
//
|
|
21
21
|
// **So the refusal is put at the launch, and it names the detached route.** The region from the gate to
|
|
22
22
|
// the merge belongs to `pnpm josh ship --detach` in a child (`chain-rule.md` step 0), whose supervisor
|
|
23
|
-
// outlives the turn.
|
|
23
|
+
// outlives the turn.
|
|
24
|
+
//
|
|
25
|
+
// **`ship` is in the set too, `--detach` or not** (joshuafolkken/kit#3027). #2457 detaches it in a child,
|
|
26
|
+
// but only after its preflight — the scoped checks — has passed in the calling process, so a
|
|
27
|
+
// backgrounded `ship` is killed at the turn's end before any supervisor exists: the #3022 child did
|
|
28
|
+
// exactly that and was parked as a failure. Issued in the foreground it returns at `launched` within the
|
|
29
|
+
// tool timeout, and the supervisor carries the rest.
|
|
24
30
|
//
|
|
25
31
|
// **Its stop-time half reads the same fact from the other side.** A backgrounded task the transcript
|
|
26
32
|
// launched but never saw finish is still running, and in a child the stop about to happen kills it —
|
|
@@ -30,7 +36,7 @@ import { run_tail } from './run-tail'
|
|
|
30
36
|
// The josh subcommands that run long enough to be backgrounded, as `time_shell` names them — canonical,
|
|
31
37
|
// so the `ga` / `g` / `fu` aliases are covered by the one spelling.
|
|
32
38
|
const LONG_RUNNING_COMMANDS: ReadonlySet<string> = new Set(
|
|
33
|
-
['gate', 'git', 'followup'].map((name) => `${time_shell.JOSH_PREFIX}${name}`),
|
|
39
|
+
['gate', 'git', 'followup', 'ship'].map((name) => `${time_shell.JOSH_PREFIX}${name}`),
|
|
34
40
|
)
|
|
35
41
|
|
|
36
42
|
const BACKGROUND_KEY = 'run_in_background'
|
|
@@ -92,11 +98,13 @@ function pending_agent_ids(tail: string): ReadonlyArray<string> {
|
|
|
92
98
|
const LANE_BACKGROUND_REASON =
|
|
93
99
|
'⛔ lane background: this session is a dispatched lane child (`JOSH_LANE_CHILD`), a headless ' +
|
|
94
100
|
'`claude -p` process whose background Bash tasks are killed when the turn ends — so a backgrounded ' +
|
|
95
|
-
'`josh gate` / `josh git` / `josh followup` never re-invokes you; it dies at `exit code
|
|
96
|
-
'(joshuafolkken/kit#2704, measured on the #2606 child: implementation, review and live
|
|
97
|
-
'done, the run parked instead of merged). Hand the gate-to-merge region to the detached
|
|
98
|
-
'instead: `pnpm josh ship --detach --review "<title> #<N>"` (add `--cite <N>`)
|
|
99
|
-
'
|
|
101
|
+
'`josh gate` / `josh git` / `josh followup` / `josh ship` never re-invokes you; it dies at `exit code ' +
|
|
102
|
+
'143` (joshuafolkken/kit#2704, measured on the #2606 child: implementation, review and live ' +
|
|
103
|
+
'verification done, the run parked instead of merged). Hand the gate-to-merge region to the detached ' +
|
|
104
|
+
'supervisor instead: `pnpm josh ship --detach --review "<title> #<N>"` (add `--cite <N>`) issued in ' +
|
|
105
|
+
'the foreground — its preflight runs in this process before the supervisor exists, so a backgrounded ' +
|
|
106
|
+
'`ship` dies with the turn (joshuafolkken/kit#3027) — then end the turn on `launched` / `busy`. ' +
|
|
107
|
+
'`.claude/skills/workflow-commands/chain-rule.md` step 0 is the single source. A ' +
|
|
100
108
|
'single check you must read before continuing runs in the foreground within the tool timeout; the ' +
|
|
101
109
|
'commit-push step does not — in a child it too belongs to the detached ship, in either spelling. This ' +
|
|
102
110
|
'rule fires on every occurrence, not once per run.'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { NEEDS_DECISION_LABEL } from '#scripts/
|
|
1
|
+
import { NEEDS_DECISION_LABEL } from '#scripts/issue/issue-labels'
|
|
2
2
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
3
|
+
import { lane_handoff } from '#scripts/lane/lane-handoff'
|
|
3
4
|
import { shell_segments } from './shell-segments'
|
|
4
5
|
|
|
5
6
|
// A dispatched lane child records its park before it stops, delivered at the call it binds on
|
|
@@ -61,7 +62,15 @@ const NOTIFY_INVOCATION = /josh\s+(?:notify|nf)\b/u
|
|
|
61
62
|
// notify appears and a `--task-type confirmation` appears. That is looser than `is_confirmation_notify`
|
|
62
63
|
// on purpose — the guard's safe direction is to read a real stop notification as present, so a run
|
|
63
64
|
// that sent one is never told it did not.
|
|
65
|
+
//
|
|
66
|
+
// **A command that sent the Telegram itself prints this line instead** (joshuafolkken/kit#3099):
|
|
67
|
+
// `run:entry` notifies from inside its own stop, so no `josh notify` invocation reaches the transcript,
|
|
68
|
+
// and the line it prints is what the tail carries. One constant, printed there and matched here.
|
|
69
|
+
const COMMAND_NOTIFY_MARKER = 'stop notified: a confirmation Telegram was sent by this command'
|
|
70
|
+
|
|
64
71
|
function mentions_confirmation_notify(text: string): boolean {
|
|
72
|
+
if (text.includes(COMMAND_NOTIFY_MARKER)) return true
|
|
73
|
+
|
|
65
74
|
return NOTIFY_INVOCATION.test(text) && CONFIRMATION_TASK_TYPE.test(text)
|
|
66
75
|
}
|
|
67
76
|
|
|
@@ -70,13 +79,18 @@ function mentions_confirmation_notify(text: string): boolean {
|
|
|
70
79
|
// confirmation stop, not on every `Bash` call in the run. `is_child_of` is the same mechanical
|
|
71
80
|
// human-or-child fact the pre-gate cut reads: a person working in a lane carries no mark and sees no
|
|
72
81
|
// refusal, and a mark that leaked in naming another issue is read as a person too.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
//
|
|
83
|
+
// **A child that handed its region to the detached ship is not parking** (joshuafolkken/kit#2962): its
|
|
84
|
+
// stop waits on nobody, so the park checklist is the wrong advice. `lane_handoff.is_handed_off` is the
|
|
85
|
+
// reading the `Stop` hook stands its notify demand down on, so the two hooks cannot disagree.
|
|
86
|
+
function is_parking_child(directory: string = process.cwd()): boolean {
|
|
87
|
+
return lane_child_marker.is_child_of(directory) && !lane_handoff.is_handed_off(directory)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function is_unparked_stop(command: string, is_child: () => boolean = is_parking_child): boolean {
|
|
77
91
|
if (!is_confirmation_notify(command)) return false
|
|
78
92
|
|
|
79
|
-
return
|
|
93
|
+
return is_child()
|
|
80
94
|
}
|
|
81
95
|
|
|
82
96
|
// **Keeping this rule is applying `needs-decision`**, the one act the park asks for before the stop.
|
|
@@ -111,8 +125,10 @@ const LANE_PARK_REASON =
|
|
|
111
125
|
'before it stops", and the park itself is `backlogrun-park.md` → "park and continue".'
|
|
112
126
|
|
|
113
127
|
const lane_park = {
|
|
128
|
+
COMMAND_NOTIFY_MARKER,
|
|
114
129
|
LANE_PARK_REASON,
|
|
115
130
|
is_confirmation_notify,
|
|
131
|
+
is_parking_child,
|
|
116
132
|
is_unparked_stop,
|
|
117
133
|
mentions_confirmation_notify,
|
|
118
134
|
records_the_park,
|
|
@@ -76,6 +76,6 @@ const ROWS: ReadonlyArray<DeliveredRule> = oracle_firing
|
|
|
76
76
|
.firing_oracles()
|
|
77
77
|
.map(({ oracle, firing_point }) => row_for(oracle, firing_point))
|
|
78
78
|
|
|
79
|
-
const oracle_consulted = { ROWS,
|
|
79
|
+
const oracle_consulted = { ROWS, reason_for }
|
|
80
80
|
|
|
81
81
|
export { oracle_consulted }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { destructive_command } from './destructive-command'
|
|
2
|
+
import { index_guard } from './index-guard'
|
|
3
|
+
import { protected_files } from './protected-files'
|
|
4
|
+
|
|
5
|
+
// The three rows that close the deny-list bypasses (joshuafolkken/kit#2983), gathered so
|
|
6
|
+
// `delivered-rules.ts` spreads one entry. Each reads argv or a file path rather than a glob: an index
|
|
7
|
+
// mutation in any git spelling, a recursive forced `rm` or a destructive `gh` call, and a Read of
|
|
8
|
+
// `.env` or an edit of a consumer's `.claude/settings.json`. Their triggers are disjoint from every
|
|
9
|
+
// other row's — `git restore` is split with `worktree-mutation` by `--staged` alone.
|
|
10
|
+
const ROWS = [index_guard.ROW, destructive_command.ROW, protected_files.ROW] as const
|
|
11
|
+
|
|
12
|
+
const permission_guards = { ROWS }
|
|
13
|
+
|
|
14
|
+
export { permission_guards }
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { doctor_consumer } from '#scripts/doctor/doctor-consumer'
|
|
3
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
4
|
+
import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
|
|
5
|
+
|
|
6
|
+
// The trigger and the delivered text behind the `protected-file` row of `delivered-rules.ts`
|
|
7
|
+
// (joshuafolkken/kit#2983): the two files a run's own file tools must not touch.
|
|
8
|
+
//
|
|
9
|
+
// - **`.env` is never read.** It carries the Telegram bot token, and a Read lands it in the transcript.
|
|
10
|
+
// The scripts that need it load it in their own process, so refusing the tool costs them nothing.
|
|
11
|
+
// - **`.claude/settings.json` is never edited in a consumer repository.** It is the deny list and the
|
|
12
|
+
// hooks that enforce every other rule, so a run that rewrites it can switch the guards off; `josh
|
|
13
|
+
// sync` owns it there. Only a kit consumer's file is refused — decided per file from the repository
|
|
14
|
+
// the settings file sits in, not the session's directory — so kit's own edits (it is the file's
|
|
15
|
+
// source) and the user-level `~/.claude/settings.json`, which belongs to no repository, both pass.
|
|
16
|
+
//
|
|
17
|
+
// It fires on every occurrence, for the reason `git-force.ts` does.
|
|
18
|
+
|
|
19
|
+
const READ_TOOL = 'Read'
|
|
20
|
+
const EDIT_TOOLS: ReadonlySet<string> = new Set(['Edit', 'Write'])
|
|
21
|
+
const ENVIRONMENT_FILE = '.env'
|
|
22
|
+
const SETTINGS_FILE = path.join('.claude', 'settings.json')
|
|
23
|
+
|
|
24
|
+
function file_path_of(call: GuardedCall): string {
|
|
25
|
+
if (!json_value.is_record(call.input)) return ''
|
|
26
|
+
|
|
27
|
+
const value = call.input['file_path']
|
|
28
|
+
|
|
29
|
+
return typeof value === 'string' ? value : ''
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function is_environment_read(call: GuardedCall): boolean {
|
|
33
|
+
return call.name === READ_TOOL && path.basename(file_path_of(call)) === ENVIRONMENT_FILE
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// The repository the settings file belongs to is two levels above it (`<root>/.claude/settings.json`).
|
|
37
|
+
function is_consumer_settings_edit(
|
|
38
|
+
call: GuardedCall,
|
|
39
|
+
is_kit_consumer: (root: string) => boolean,
|
|
40
|
+
): boolean {
|
|
41
|
+
if (!EDIT_TOOLS.has(call.name)) return false
|
|
42
|
+
|
|
43
|
+
const file_path = path.resolve(file_path_of(call))
|
|
44
|
+
|
|
45
|
+
if (!file_path.endsWith(`${path.sep}${SETTINGS_FILE}`)) return false
|
|
46
|
+
|
|
47
|
+
return is_kit_consumer(path.dirname(path.dirname(file_path)))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function is_protected_file_call(
|
|
51
|
+
call: GuardedCall,
|
|
52
|
+
is_kit_consumer: (root: string) => boolean = doctor_consumer.is_kit_consumer,
|
|
53
|
+
): boolean {
|
|
54
|
+
return is_environment_read(call) || is_consumer_settings_edit(call, is_kit_consumer)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const PROTECTED_FILE_REASON =
|
|
58
|
+
'⛔ protected file: `.env` holds the Telegram bot token, so reading it puts a secret in the ' +
|
|
59
|
+
'transcript — the scripts that need it load it in their own process. `.claude/settings.json` in a ' +
|
|
60
|
+
'consumer repository is the deny list and the hooks every other rule rests on, so a run must not ' +
|
|
61
|
+
'rewrite it; `josh sync` owns it, and a change belongs upstream in kit (`CLAUDE.md` → "Route ' +
|
|
62
|
+
'distributed-doc / config changes upstream to kit"). Leave both files alone, or ask the user. ' +
|
|
63
|
+
'**This rule fires on every occurrence, not once per run.**'
|
|
64
|
+
|
|
65
|
+
const ROW = {
|
|
66
|
+
id: 'protected-file',
|
|
67
|
+
is_trigger: is_protected_file_call,
|
|
68
|
+
reason: PROTECTED_FILE_REASON,
|
|
69
|
+
decide: (): boolean => true,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const protected_files = { ROW, is_protected_file_call }
|
|
73
|
+
|
|
74
|
+
export { protected_files }
|
|
@@ -111,6 +111,6 @@ function is_mismatch(message: string, lang: string): boolean {
|
|
|
111
111
|
return matches_share(prose, script, pattern) < MATCH_SHARE_FLOOR
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
const reply_language = {
|
|
114
|
+
const reply_language = { is_mismatch, script_of }
|
|
115
115
|
|
|
116
116
|
export { reply_language }
|