@bensandee/tooling 0.81.1 → 0.83.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bensandee/tooling",
3
- "version": "0.81.1",
3
+ "version": "0.83.0",
4
4
  "description": "CLI tool to bootstrap and maintain standardized TypeScript project tooling",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -30,29 +30,31 @@
30
30
  "registry": "https://registry.npmjs.org"
31
31
  },
32
32
  "dependencies": {
33
- "@bensandee/common": "0.1.4",
33
+ "@bensandee/common": "0.2.0",
34
34
  "@clack/prompts": "^1.8.1",
35
35
  "citty": "^0.2.2",
36
36
  "cross-spawn": "^7.0.6",
37
- "dependency-cruiser": "^18.3.1",
37
+ "dependency-cruiser": "^18.4.0",
38
38
  "json5": "^2.2.3",
39
39
  "jsonc-parser": "^3.3.1",
40
40
  "picomatch": "^4.0.7",
41
- "smol-toml": "^1.8.0",
41
+ "smol-toml": "^1.9.0",
42
42
  "yaml": "^2.9.1",
43
43
  "zod": "^4.6.5"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@bensandee/claude-hooks": "0.12.0",
47
- "@bensandee/forgejo": "0.6.0",
47
+ "@bensandee/cli-kit": "0.0.0",
48
+ "@bensandee/forgejo": "0.7.0",
48
49
  "@changesets/cli": "3.0.3",
49
50
  "@release-it/bumper": "8.0.1",
50
51
  "@types/cross-spawn": "6.0.6",
51
52
  "@types/node": "24.13.5",
52
53
  "@types/picomatch": "4.0.3",
53
54
  "commit-and-tag-version": "13.2.1",
54
- "oxfmt": "0.68.0",
55
- "prettier": "3.9.8",
55
+ "modern-web-guidance": "0.0.191",
56
+ "oxfmt": "0.71.0",
57
+ "prettier": "3.9.9",
56
58
  "release-it": "21.1.0",
57
59
  "tsdown": "0.23.0"
58
60
  },
@@ -605,13 +605,36 @@
605
605
  "type": "boolean"
606
606
  },
607
607
  "preRunRebase": {
608
- "description": "Attempt a clean-only rebase of the work branch onto the default branch before the implement (execute) phase's container starts (default true). A clean rebase runs the container on the rebased branch; a conflicting one is aborted, reported on the run's ledger comment, and the run still proceeds on the un-rebased branch for a later agent/repair cycle to resolve -- it never fails the run. Set false to skip the attempt entirely for this repo: no fetch, no rebase, no abort, and the branch is worked exactly as cloned.",
608
+ "description": "Attempt a clean-only rebase of the work branch onto the default branch before the implement (execute) phase's container starts (default true). A clean rebase runs the container on the rebased branch; a conflicting one is aborted, reported on the run's status comment, and the run still proceeds on the un-rebased branch -- it never fails the run. Two consecutive conflicting attempts hand the unit to agent/repair before any container runs, unless the branch already contains the default branch (a hand-made merge, which leaves a repair nothing to rebase), and a timeout or a failed rebase never counts toward that pair. Set false to skip the attempt entirely for this repo: no fetch, no rebase, no abort, and the branch is worked exactly as cloned.",
609
609
  "type": "boolean"
610
610
  },
611
611
  "backlog": {
612
612
  "description": "Whether the agent may self-trigger backlog runs consuming this repo's .agent/findings/ ledger (default: on wherever the ledger exists, which only happens in a repo whose own review loop wrote it). A backlog run opens a pull request that fixes or refutes the pending findings; false disarms it, leaving the ledger to accumulate for a human.",
613
613
  "type": "boolean"
614
614
  },
615
+ "lintSweep": {
616
+ "description": "The lint-warning sweep: a periodic agent job that measures this repo's oxlint warnings on its default branch in a container and, past minWarnings, opens a pull request carrying a generated plan for an agent/implement run to work off.",
617
+ "type": "object",
618
+ "properties": {
619
+ "enabled": {
620
+ "description": "Whether the agent's lint-warning sweep may open pull requests in this repo (default: on). false disarms it; the repo is then never cloned or measured by it.",
621
+ "type": "boolean"
622
+ },
623
+ "minWarnings": {
624
+ "description": "How many oxlint warnings the default branch must carry before the sweep opens a pull request (default 5). Below the floor the warn marker on checks:run is the whole response.",
625
+ "type": "integer",
626
+ "minimum": 0,
627
+ "maximum": 9007199254740991
628
+ },
629
+ "cooldownDays": {
630
+ "description": "Days after a lint-sweep pull request merged or closed before the sweep may open another (default 7): a merged sweep whose declined warnings survive must not re-file them the next morning.",
631
+ "type": "integer",
632
+ "minimum": 0,
633
+ "maximum": 9007199254740991
634
+ }
635
+ },
636
+ "additionalProperties": false
637
+ },
615
638
  "priority": {
616
639
  "description": "Map this repo's own issue-label names onto the agent's four priority levels, e.g. {\"P1\": \"critical\", \"P4\": \"low\"}. The map UNIONS with the built-in priority/<level> names rather than replacing them, and the agent does not create aliased labels -- the repo owns names the agent did not choose. Priority affects claim order only: it never changes a run's model, effort, or any budget.",
617
640
  "type": "object",
@@ -626,6 +649,77 @@
626
649
  "triageAnalysis": {
627
650
  "description": "Whether the agent may route its own agent-note/human-triage-needed issues through the agent/analyze stage (default: off). Unlike agent.backlog, which defaults on, this defaults off: a backlog run batches every pending finding into one container, while triage routing spends one container per issue -- arming it is the reversible direction, not disarming it.",
628
651
  "type": "boolean"
652
+ },
653
+ "findingHolds": {
654
+ "description": "Which of a pull request's linked open findings withhold its unattended merge. `rules` is ordered and the first `when` that matches decides; no match falls through to `default`; an absent block is { rules: [], default: true }, so every open linked finding holds by default. Read off the repo's DEFAULT BRANCH, never off the pull request's own tree -- a pull request cannot edit the rule deciding whether it is held. In a `mentions` entry a /.../flags pattern is a regular expression and anything else is a case-insensitive substring.",
655
+ "type": "object",
656
+ "properties": {
657
+ "rules": {
658
+ "default": [],
659
+ "description": "Ordered rules; the first whose `when` matches decides, and no match falls through to `default`.",
660
+ "type": "array",
661
+ "items": {
662
+ "type": "object",
663
+ "properties": {
664
+ "when": {
665
+ "description": "The clause this rule matches on -- a conjunction of optional matchers, all of which must match. An absent clause matches every finding; a matcher that is present may not be empty.",
666
+ "type": "object",
667
+ "properties": {
668
+ "class": {
669
+ "description": "Match when the finding's class is any of these. Only human-decision findings become issues today, so this matcher exists for a class a later change files as one; it is declared now so a rule using it does not need the schema to change under it.",
670
+ "minItems": 1,
671
+ "type": "array",
672
+ "items": {
673
+ "type": "string",
674
+ "enum": ["human-decision", "pre-existing", "nit"]
675
+ }
676
+ },
677
+ "phase": {
678
+ "description": "Match when the phase of the run that filed the finding is any of these (review, spec, plan, implement, ...). Distinguishes, for example, a finding filed by spec work against a docs-only pull request from one a review raised on the code.",
679
+ "minItems": 1,
680
+ "type": "array",
681
+ "items": {
682
+ "type": "string",
683
+ "minLength": 1
684
+ }
685
+ },
686
+ "mentions": {
687
+ "description": "Match when the finding's title or body prose contains any of these. A plain string is a case-insensitive substring; a pattern written /.../flags is a regular expression. This is how a rule looks at which files a finding concerns: a finding about health-baseline.json says so in its text.",
688
+ "minItems": 1,
689
+ "type": "array",
690
+ "items": {
691
+ "type": "string",
692
+ "minLength": 1
693
+ }
694
+ },
695
+ "prLabels": {
696
+ "description": "Match when the pull request carries any of these labels (from the claim snapshot).",
697
+ "minItems": 1,
698
+ "type": "array",
699
+ "items": {
700
+ "type": "string",
701
+ "minLength": 1
702
+ }
703
+ }
704
+ },
705
+ "additionalProperties": false
706
+ },
707
+ "hold": {
708
+ "type": "boolean",
709
+ "description": "What this rule decides: true withholds the pull request from unattended merging, false lets it through."
710
+ }
711
+ },
712
+ "required": ["hold"],
713
+ "additionalProperties": false
714
+ }
715
+ },
716
+ "default": {
717
+ "default": true,
718
+ "description": "What to do with a finding no rule matched (default true -- hold). Failing closed is the deliberate shipped default: an unwanted hold costs one tap to answer the finding, while an unwanted pass is the problem the gate exists to prevent.",
719
+ "type": "boolean"
720
+ }
721
+ },
722
+ "additionalProperties": false
629
723
  }
630
724
  },
631
725
  "additionalProperties": false
@@ -641,7 +735,7 @@
641
735
  "maximum": 9007199254740991
642
736
  },
643
737
  "backupDays": {
644
- "description": "Days before bst branch:prune deletes an agent/(repair|rebase)-backup/* ref whose parent branch has no merged PR to key on (default 30). Deliberately longer than mergedDays: a backup ref is the only surviving copy of history rebased away from its parent. Zero is valid on purpose, matching the --backup-days CLI flag's contract.",
738
+ "description": "Days before bst branch:prune deletes an agent/(repair|rebase|failover)-backup/* ref whose parent branch has no merged PR to key on (default 30). Deliberately longer than mergedDays: a backup ref may be the only surviving copy of the work it holds. Zero is valid on purpose, matching the --backup-days CLI flag's contract.",
645
739
  "type": "integer",
646
740
  "minimum": 0,
647
741
  "maximum": 9007199254740991
@@ -656,41 +750,6 @@
656
750
  },
657
751
  "additionalProperties": false
658
752
  },
659
- "labelSets": {
660
- "description": "User-defined label sets for `bst forgejo:labels sync --set <name>`, keyed by set name. Read from the repo the command runs in, never from a --repo/--fleet target. A name that collides with a built-in set (e.g. the agent package's own 'agent' set) is a resolution-time error, not a silent override.",
661
- "type": "object",
662
- "propertyNames": {
663
- "type": "string"
664
- },
665
- "additionalProperties": {
666
- "type": "array",
667
- "items": {
668
- "type": "object",
669
- "properties": {
670
- "name": {
671
- "type": "string",
672
- "minLength": 1,
673
- "description": "The label's full name, e.g. 'area/frontend'"
674
- },
675
- "color": {
676
- "type": "string",
677
- "pattern": "^#[0-9a-fA-F]{6}$",
678
- "description": "Hex color with a leading '#', e.g. '#1f6feb'"
679
- },
680
- "description": {
681
- "type": "string",
682
- "description": "Shown in the forge UI beside the label"
683
- },
684
- "exclusive": {
685
- "description": "Forgejo scoped-label exclusivity: at most one label of this set's scope per issue/PR (default false)",
686
- "type": "boolean"
687
- }
688
- },
689
- "required": ["name", "color", "description"],
690
- "additionalProperties": false
691
- }
692
- }
693
- },
694
753
  "issues": {
695
754
  "description": "Repo-level issue policy -- currently just the default reviewer(s) `bst issue:create` assigns. The natural home for any future issue-policy key.",
696
755
  "type": "object",