@joshuafolkken/kit 1.1387.0 → 1.1453.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/skills/epic-commands/SKILL.md +1 -1
- package/.claude/skills/epic-commands/epic-bundle.md +5 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +5 -3
- package/.claude/skills/workflow-commands/backlogrun-park.md +2 -0
- package/.claude/skills/workflow-commands/backlogrun-steps.md +13 -10
- package/.claude/skills/workflow-commands/backlogrun.md +3 -2
- package/.claude/skills/workflow-commands/chain-rule.md +4 -2
- package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
- package/.claude/skills/workflow-commands/halfrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-comments.md +6 -0
- package/.claude/skills/workflow-commands/kickoff.md +12 -13
- package/.claude/skills/workflow-commands/observation-filing.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +3 -2
- package/.claude/skills/workflow-commands/pre-gate-cut.md +5 -3
- package/.claude/skills/workflow-commands/prerequisite.md +6 -0
- package/.claude/skills/workflow-commands/retrospective.md +5 -5
- package/.claude/skills/workflow-commands/split-assessment.md +2 -2
- package/README.md +27 -4
- package/dist/hooks/audit-provision.js +2 -2
- package/dist/hooks/batch-guard.js +7 -7
- package/dist/hooks/{chunk-2YSW3CXH.js → chunk-3C4XRYG6.js} +35 -11
- package/dist/hooks/{chunk-GJ7JPIHN.js → chunk-5C7L6FRC.js} +2704 -190
- package/dist/hooks/{chunk-FZ6FUSBM.js → chunk-723HKZO5.js} +1 -1
- package/dist/hooks/{chunk-STDSEPWU.js → chunk-D3NJXN5M.js} +4 -4
- package/dist/hooks/{chunk-NEC4AT4Z.js → chunk-DGT54IH5.js} +4 -0
- package/dist/hooks/{chunk-LMWBRJIP.js → chunk-EF5GQ6WS.js} +3 -3
- package/dist/hooks/{chunk-JBBMAPC4.js → chunk-IX6TTTI6.js} +4 -0
- package/dist/hooks/{chunk-IYVOLN6A.js → chunk-LBFYEOXJ.js} +3 -3
- package/dist/hooks/{chunk-SL4GQ2XP.js → chunk-MBJYQPEK.js} +106 -23
- package/dist/hooks/{chunk-WNFJLBXI.js → chunk-NO4AALP5.js} +3 -3
- package/dist/hooks/{chunk-J3KSS7II.js → chunk-OLMO72ON.js} +1 -1
- package/dist/hooks/{chunk-DCY2GWHC.js → chunk-SHYUQOIS.js} +5 -5
- package/dist/hooks/{chunk-EAQEGME7.js → chunk-UT7YC3N2.js} +1 -1
- package/dist/hooks/{chunk-EBSHN25W.js → chunk-W5ZKGTSY.js} +4 -4
- package/dist/hooks/{chunk-GNDJ7NJ7.js → chunk-Y3GKIKGW.js} +209 -56
- package/dist/hooks/{chunk-U32VSRNG.js → chunk-Z4XI7CZS.js} +89 -34
- package/dist/hooks/codex-hook-adapter.js +15 -15
- package/dist/hooks/duplicate-read-guard.js +8 -8
- package/dist/hooks/format-edited.js +5 -5
- package/dist/hooks/inputs.json +261 -201
- package/dist/hooks/investigation-guard.js +8 -8
- package/dist/hooks/pretool-guard.js +14 -14
- package/dist/hooks/session-lang.js +69 -16
- package/dist/hooks/stop-guard.js +13 -38
- package/dist/josh.js +95 -19
- package/package.json +4 -3
- package/prompts/collaboration-workflow/issue-template.md +10 -8
- package/prompts/review.md +30 -4
- package/scripts/agent/claude-agent-argv.ts +13 -1
- package/scripts/auth/auth-setup-cli.ts +101 -0
- package/scripts/auth/claude-token-output.ts +78 -0
- package/scripts/auth/claude-token.ts +68 -0
- package/scripts/auto-ok/auto-ok-judge-cli.ts +125 -0
- package/scripts/auto-ok/auto-ok-judge-read.ts +95 -0
- package/scripts/auto-ok/auto-ok-judge-write.ts +109 -0
- package/scripts/auto-ok/auto-ok-judge.ts +67 -0
- package/scripts/backlog/backlog-drive-cli.ts +14 -0
- package/scripts/backlog/backlog-drive-epic.ts +24 -8
- package/scripts/backlog/backlog-drive-launch.ts +3 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +7 -2
- package/scripts/backlog/backlog-drive-named.ts +4 -2
- package/scripts/backlog/backlog-drive-unread.ts +56 -0
- package/scripts/backlog/backlog-drive.ts +38 -11
- package/scripts/backlog/backlog-overlap.ts +22 -5
- package/scripts/backlog/backlog-ready.ts +1 -3
- package/scripts/backlog/backlogrun-args.ts +13 -2
- package/scripts/backlog/backlogrun-cli.ts +91 -19
- package/scripts/backlog/backlogrun-launch.ts +24 -0
- package/scripts/backlog/backlogrun-replace.ts +166 -0
- package/scripts/backlog/backlogrun-stop.ts +178 -0
- package/scripts/behavior/behavior-cli.ts +6 -1
- package/scripts/doctor/doctor-io.ts +60 -9
- package/scripts/doctor/doctor.ts +20 -1
- package/scripts/document/document-byte-budget.ts +3 -3
- package/scripts/epic/epic-bundle-cli.ts +8 -8
- package/scripts/epic/epic-bundle-referenced.ts +2 -5
- package/scripts/epic/epic-bundle.ts +39 -4
- package/scripts/exports/unused-members-cli.ts +2 -1
- package/scripts/followup/followup-checks-event.ts +82 -0
- package/scripts/followup/git-followup-finish.ts +16 -2
- package/scripts/followup/git-followup-workflow.ts +5 -2
- package/scripts/followup/git-pr-followup-checks.ts +18 -4
- package/scripts/followup/git-pr-followup-wrapup.ts +5 -0
- package/scripts/followup/git-pr-followup.ts +4 -1
- package/scripts/fresh-machine/fresh-machine-cli.ts +204 -0
- package/scripts/fresh-machine/fresh-machine-docker.ts +65 -0
- package/scripts/fresh-machine/fresh-machine-image.ts +62 -0
- package/scripts/fresh-machine/fresh-machine-log.ts +61 -0
- package/scripts/fresh-machine/fresh-machine-patterns.ts +175 -0
- package/scripts/fresh-machine/fresh-machine-run.ts +215 -0
- package/scripts/fresh-machine/fresh-machine-script.ts +45 -0
- package/scripts/fresh-machine/fresh-machine-spec.ts +57 -0
- package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +34 -0
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +31 -0
- package/scripts/gate/gate-report.ts +70 -15
- package/scripts/gate/project-checks.ts +18 -4
- package/scripts/gate/scoped-green.ts +2 -1
- package/scripts/gate/verification-gate.ts +4 -3
- package/scripts/gh/gh-author-association.ts +14 -0
- package/scripts/gh/git-gh-conditional.ts +66 -0
- package/scripts/gh/git-gh-exec.ts +1 -1
- package/scripts/gh/git-gh-issue-read.ts +6 -3
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +5 -1
- package/scripts/gh/git-gh-issue.ts +13 -1
- package/scripts/gh/git-pr-checks-eval.ts +13 -0
- package/scripts/gh/git-pr-checks-parse.ts +8 -1
- package/scripts/gh/git-pr-checks-watch.ts +11 -4
- package/scripts/gh/git-pr-checks.ts +36 -2
- package/scripts/git/git-command.ts +16 -4
- package/scripts/git/git-schemas.ts +1 -0
- package/scripts/git/git-spawn-sync.ts +1 -1
- package/scripts/hooks/pretool-guard.ts +3 -1
- package/scripts/init/hook-command-rewrite.ts +31 -0
- package/scripts/init/init-actions.ts +7 -4
- package/scripts/init/init-ai-copy.ts +34 -11
- package/scripts/init/init-basic.ts +9 -4
- package/scripts/init/init-bootstrap.ts +6 -2
- package/scripts/init/init-dry-run-report.ts +150 -0
- package/scripts/init/init-dry-run.ts +189 -0
- package/scripts/init/init-install.ts +8 -1
- package/scripts/init/init-logic-toolchain.ts +76 -0
- package/scripts/init/init-logic.ts +2 -0
- package/scripts/init/init.ts +62 -42
- package/scripts/init/kit-setup-state.ts +11 -17
- package/scripts/init/own-formatter.ts +21 -0
- package/scripts/init/project-profile.ts +60 -12
- package/scripts/init/start-dry-run.ts +70 -0
- package/scripts/init/start-exec.ts +27 -1
- package/scripts/init/start-plan.ts +23 -3
- package/scripts/init/start-setup-pr.ts +13 -24
- package/scripts/init/start-steps.ts +62 -1
- package/scripts/init/start.ts +38 -17
- package/scripts/init/workflow-mark.ts +35 -0
- package/scripts/init/working-tree.ts +116 -0
- package/scripts/issue/issue-ack-cli.ts +84 -0
- package/scripts/issue/issue-auto-ok.ts +68 -99
- package/scripts/issue/issue-file-cli.ts +17 -17
- package/scripts/issue/issue-file.ts +1 -6
- package/scripts/issue/issue-labels.ts +46 -10
- package/scripts/issue/issue-release-cli.ts +69 -23
- package/scripts/issue/issue-release.ts +3 -1
- package/scripts/issue/issue-state-cli.ts +14 -4
- package/scripts/issue/issue-watch-diff.ts +152 -0
- package/scripts/issue/issue-watch-gate.ts +81 -0
- package/scripts/issue/issue-watch-hook.ts +54 -0
- package/scripts/issue/issue-watch.ts +240 -0
- package/scripts/issue/measure-rerun-cli.ts +3 -4
- package/scripts/josh/josh-command-map.ts +4 -0
- package/scripts/josh/josh-commands-ai.ts +11 -0
- package/scripts/josh/josh-commands-backlog.ts +2 -2
- package/scripts/josh/josh-commands-development.ts +1 -1
- package/scripts/josh/josh-commands-issue.ts +10 -3
- package/scripts/josh/josh-commands-lane.ts +11 -2
- package/scripts/josh/josh-commands-project.ts +26 -2
- package/scripts/josh/josh-verdict.ts +33 -4
- package/scripts/josh/process-identity.ts +32 -6
- package/scripts/lane/claude-lane-broker.ts +142 -0
- package/scripts/lane/lane-await.ts +6 -2
- package/scripts/lane/lane-broker-server.ts +69 -0
- package/scripts/lane/lane-cache.ts +37 -7
- package/scripts/lane/lane-capacity.ts +8 -6
- package/scripts/lane/lane-child-invocation.ts +1 -0
- package/scripts/lane/lane-cli.ts +15 -1
- package/scripts/lane/lane-close.ts +15 -6
- package/scripts/lane/lane-dispatch.ts +36 -10
- package/scripts/lane/lane-environment.ts +1 -1
- package/scripts/lane/lane-launch-cli.ts +13 -4
- package/scripts/lane/lane-ledger.ts +21 -3
- package/scripts/lane/lane-measure-cli.ts +10 -2
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-preserve.ts +49 -0
- package/scripts/lane/lane-reap.ts +20 -5
- package/scripts/lane/lane-registry.ts +6 -0
- package/scripts/lane/lane-restart-cli.ts +51 -0
- package/scripts/lane/lane-restart.ts +175 -0
- package/scripts/lane/lane-session-broker.ts +363 -0
- package/scripts/lane/lane-spent.ts +195 -0
- package/scripts/lane/lane-stage-stats.ts +27 -3
- package/scripts/lane/lane-stop-stats.ts +96 -0
- package/scripts/lane/openai-lane-supervisor.ts +2 -2
- package/scripts/lane/process-tools.ts +31 -0
- package/scripts/lib/buffered-process.ts +36 -2
- package/scripts/lib/pnpm-reach.ts +27 -0
- package/scripts/lib/status-icons.ts +5 -1
- package/scripts/lint/lint-parallel.ts +19 -2
- package/scripts/observations/observation-ledger-home.ts +1 -0
- package/scripts/observations/observation-ledger-migrate.ts +3 -15
- package/scripts/release/release-issue-close.ts +133 -0
- package/scripts/release/release-publish.ts +12 -1
- package/scripts/repo/repository-labels.ts +11 -1
- package/scripts/review/comment-ranges.ts +199 -0
- package/scripts/review/review-attest-cli.ts +21 -6
- package/scripts/review/review-brief-cli.ts +24 -7
- package/scripts/review/review-code-tree.ts +119 -0
- package/scripts/review/review-comment-round.ts +114 -0
- package/scripts/review/review-record-cli.ts +39 -17
- package/scripts/review/review-round2-cli.ts +16 -5
- package/scripts/review/review-round2.ts +30 -10
- package/scripts/review/review-stamps.ts +22 -1
- package/scripts/rules/implementation-cut.ts +3 -3
- package/scripts/rules/pre-gate-cut.ts +1 -1
- package/scripts/run/board/run-board-checks.ts +42 -0
- package/scripts/run/board/run-board-cli.ts +2 -0
- package/scripts/run/board/run-board-every.ts +3 -1
- package/scripts/run/board/run-board-fit.ts +16 -5
- package/scripts/run/board/run-board-fresh.ts +64 -0
- package/scripts/run/board/run-board-header.ts +129 -53
- package/scripts/run/board/run-board-labels.ts +47 -4
- package/scripts/run/board/run-board-lane-event.ts +66 -0
- package/scripts/run/board/run-board-layout.ts +57 -9
- package/scripts/run/board/run-board-now.ts +234 -0
- package/scripts/run/board/run-board-operation-read.ts +75 -0
- package/scripts/run/board/run-board-operation.ts +150 -0
- package/scripts/run/board/run-board-phase.ts +26 -1
- package/scripts/run/board/run-board-plan.ts +4 -6
- package/scripts/run/board/run-board-read.ts +49 -3
- package/scripts/run/board/run-board-reason.ts +124 -0
- package/scripts/run/board/run-board-render-checks.ts +55 -0
- package/scripts/run/board/run-board-render-legend.ts +12 -3
- package/scripts/run/board/run-board-render-slot.ts +2 -2
- package/scripts/run/board/run-board-render-tail.ts +128 -0
- package/scripts/run/board/run-board-render-thanks.ts +50 -0
- package/scripts/run/board/run-board-render-title.ts +58 -0
- package/scripts/run/board/run-board-render.ts +96 -80
- package/scripts/run/board/run-board-row-yield.ts +32 -0
- package/scripts/run/board/run-board-setup.ts +61 -13
- package/scripts/run/board/run-board-state.ts +10 -0
- package/scripts/run/board/run-board-status.ts +66 -7
- package/scripts/run/board/run-board-thanks-csv.ts +71 -0
- package/scripts/run/board/run-board-thanks-read.ts +112 -0
- package/scripts/run/board/run-board-thanks.ts +53 -0
- package/scripts/run/board/run-board-tick.ts +50 -21
- package/scripts/run/board/run-board-usual.ts +44 -0
- package/scripts/run/carry/run-carry-args.ts +9 -1
- package/scripts/run/carry/run-carry-cli.ts +2 -45
- package/scripts/run/carry/run-carry-end.ts +73 -0
- package/scripts/run/carry/run-carry.ts +8 -1
- package/scripts/run/entry/run-entry-cli.ts +5 -0
- package/scripts/run/event/run-event-checks.ts +54 -0
- package/scripts/run/event/run-event-render.ts +2 -0
- package/scripts/run/event/run-event-scope.ts +1 -0
- package/scripts/run/event/run-event-setup.ts +55 -11
- package/scripts/run/event/run-event-stream.ts +27 -11
- package/scripts/run/merge/run-merge-cli.ts +7 -4
- package/scripts/run/merge/run-merge-ship.ts +61 -0
- package/scripts/run/merge/run-merge-steps.ts +7 -14
- package/scripts/run/merge/run-merge-token.ts +16 -2
- package/scripts/run/run-headless.ts +1 -0
- package/scripts/run/run-step.ts +2 -0
- package/scripts/run/ship/run-ship-cli.ts +22 -2
- package/scripts/run/ship/run-ship-return.ts +31 -13
- package/scripts/run/ship/run-ship-review-steps.ts +17 -4
- package/scripts/run/ship/run-ship-stage.ts +1 -0
- package/scripts/run/wake/run-wake-await.ts +130 -0
- package/scripts/run/wake/run-wake-cli.ts +60 -71
- package/scripts/run/wake/run-wake-describe.ts +34 -2
- package/scripts/run/wake/run-wake-driver.ts +11 -4
- package/scripts/run/wake/run-wake-session.ts +20 -3
- package/scripts/run/wake/run-wake-stop.ts +37 -0
- package/scripts/run/wake/run-wake-supervise.ts +44 -0
- package/scripts/sync/claude-settings-merge.ts +144 -0
- package/scripts/sync/sync-ai-files.ts +28 -3
- package/scripts/sync/sync.ts +15 -0
- package/scripts/test/project-test-script.ts +73 -0
- package/scripts/test/skip-marker.ts +14 -1
- package/scripts/test/test-related.ts +3 -2
- package/scripts/test/test-unit-guard.ts +78 -14
- package/scripts/time-runtime/time-reported-failure.ts +11 -3
- package/scripts/uninstall/distributed-files.ts +92 -0
- package/scripts/uninstall/uninstall-plan.ts +119 -0
- package/scripts/uninstall/uninstall-report.ts +61 -0
- package/scripts/uninstall/uninstall.ts +206 -0
- package/templates/AGENTS.basic.md +4 -0
- package/templates/GEMINI.basic.md +6 -0
- package/dist/hooks/chunk-6V5OPIUU.js +0 -13
- package/scripts/lane/openai-review-broker.ts +0 -262
- package/scripts/run/board/run-board-track.ts +0 -22
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { git_command } from '#scripts/git/git-command'
|
|
4
|
+
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
5
|
+
import { session_cite } from '#scripts/issue/session-cite'
|
|
6
|
+
import { issue_watch, type Acknowledged } from './issue-watch'
|
|
7
|
+
|
|
8
|
+
// `josh issue:ack <N>` — record that the run has read a person's update to its issue, so the hook,
|
|
9
|
+
// the review attestation and `josh followup` stop raising it. It prints the update it acknowledges:
|
|
10
|
+
// the same read becomes the new baseline (`issue-watch.ts` → `acknowledge`), so nothing that arrived
|
|
11
|
+
// after the hook spoke can be acknowledged without being printed here.
|
|
12
|
+
//
|
|
13
|
+
// **The number is asked for, though the record already carries it**, so an acknowledgement typed for
|
|
14
|
+
// one issue cannot silently clear the watch on another.
|
|
15
|
+
|
|
16
|
+
const SUCCESS_EXIT_CODE = 0
|
|
17
|
+
const FAILURE_EXIT_CODE = 1
|
|
18
|
+
const ARGV_OFFSET = 2
|
|
19
|
+
const USAGE = 'Usage: josh issue:ack <issue-number>'
|
|
20
|
+
const NO_WATCH_LINE =
|
|
21
|
+
'No run recorded a baseline for that issue in this checkout (`josh run:entry` writes it), or the issue could not be read — nothing was acknowledged.'
|
|
22
|
+
const NOTHING_NEW_LINE = 'No person has updated the issue since the run last read it.'
|
|
23
|
+
|
|
24
|
+
function parse_number(argv: ReadonlyArray<string>): string | undefined {
|
|
25
|
+
const [first] = argv
|
|
26
|
+
|
|
27
|
+
if (first === undefined || argv.length !== 1) return undefined
|
|
28
|
+
|
|
29
|
+
return issue_number_shape.ISSUE_NUMBER_PATTERN.test(first) ? first : undefined
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function report(acknowledged: Acknowledged): void {
|
|
33
|
+
const heading = `Acknowledged issue ${session_cite.issue(acknowledged.issue)}.`
|
|
34
|
+
|
|
35
|
+
console.info(
|
|
36
|
+
acknowledged.diff === undefined
|
|
37
|
+
? `${heading} ${NOTHING_NEW_LINE}`
|
|
38
|
+
: `${heading}\n\n${acknowledged.diff}`,
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function acknowledge(issue_number: string): Promise<number> {
|
|
43
|
+
const root = await git_command.repository_root()
|
|
44
|
+
|
|
45
|
+
if (issue_watch.read_record(root)?.issue !== issue_number) {
|
|
46
|
+
console.error(NO_WATCH_LINE)
|
|
47
|
+
|
|
48
|
+
return FAILURE_EXIT_CODE
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const acknowledged = await issue_watch.acknowledge(root)
|
|
52
|
+
|
|
53
|
+
if (acknowledged === undefined) {
|
|
54
|
+
console.error(NO_WATCH_LINE)
|
|
55
|
+
|
|
56
|
+
return FAILURE_EXIT_CODE
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
report(acknowledged)
|
|
60
|
+
|
|
61
|
+
return SUCCESS_EXIT_CODE
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function run(argv: ReadonlyArray<string>): Promise<number> {
|
|
65
|
+
const issue_number = parse_number(argv)
|
|
66
|
+
|
|
67
|
+
if (issue_number === undefined) {
|
|
68
|
+
console.error(USAGE)
|
|
69
|
+
|
|
70
|
+
return FAILURE_EXIT_CODE
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return await acknowledge(issue_number)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function main(argv: ReadonlyArray<string>): Promise<void> {
|
|
77
|
+
process.exitCode = await run(argv)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const issue_ack_cli = { run }
|
|
81
|
+
|
|
82
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
|
|
83
|
+
|
|
84
|
+
export { issue_ack_cli }
|
|
@@ -1,34 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// `
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
import {
|
|
2
|
+
BREAKING_CHANGE_LABEL,
|
|
3
|
+
DEFERRED_LABEL,
|
|
4
|
+
EPIC_LABEL,
|
|
5
|
+
has_label_name,
|
|
6
|
+
NEEDS_HUMAN_REVIEW_LABEL,
|
|
7
|
+
RELEASE_LABEL,
|
|
8
|
+
} from './issue-labels'
|
|
9
|
+
import { markdown_section } from './markdown-section'
|
|
10
|
+
|
|
11
|
+
// Whether `josh issue:file` applies `auto-ok` to the Issue it files, judged against the criteria
|
|
12
|
+
// `docs/how-to/run-backlog.md` records rather than the context the filing happens in, so a filing a
|
|
13
|
+
// person asked for (`kickoff new`) is judged the same as one an agent makes on its own. The answer is
|
|
14
|
+
// a pure reading of the filing — its labels, its body and its target — so `backlogrun`'s judgement
|
|
15
|
+
// of an Issue already open reuses `exclusion_of` rather than a second list (joshuafolkken/kit#3854).
|
|
16
|
+
// The order: `--no-auto-ok`, a filing to another repository (whose own `backlogrun` would implement
|
|
17
|
+
// and merge it though nobody opted that repository in), a label that keeps a person in the loop, and
|
|
18
|
+
// last the body's judgement declaration (`JUDGEMENT_NEEDED` / `JUDGEMENT_NOT_NEEDED`): whether a
|
|
19
|
+
// policy decision, an external account or a human visual check is needed.
|
|
20
|
+
|
|
21
|
+
interface AutoOkFiling {
|
|
22
|
+
// `--no-auto-ok`: the filer declared the Issue needs a person's judgement.
|
|
23
23
|
is_opted_out: boolean
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
is_carried: boolean
|
|
29
|
-
// The labels of the Issue the current branch names; `undefined` when the branch names none or the
|
|
30
|
-
// Issue could not be read.
|
|
31
|
-
branch_labels: ReadonlyArray<string> | undefined
|
|
24
|
+
is_cross_repository: boolean
|
|
25
|
+
// Every label the filing carries, including the ones the body's declarations add.
|
|
26
|
+
labels: ReadonlyArray<string>
|
|
27
|
+
body: string
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
interface AutoOkDecision {
|
|
@@ -36,98 +32,71 @@ interface AutoOkDecision {
|
|
|
36
32
|
reason: string
|
|
37
33
|
}
|
|
38
34
|
|
|
35
|
+
const BACKGROUND_HEADING = '## 背景'
|
|
36
|
+
const JUDGEMENT_NOT_NEEDED = '- 人の判断: 不要'
|
|
37
|
+
const JUDGEMENT_NEEDED = '- 人の判断: 要'
|
|
38
|
+
const DECLARATION_PROBLEM = `declare under \`${BACKGROUND_HEADING}\` whether a person's judgement (a policy decision, an external account, a human visual check) is needed: \`${JUDGEMENT_NOT_NEEDED}\` or \`${JUDGEMENT_NEEDED}(<which one>)\` — exactly one (\`issue-template.md\`)`
|
|
39
|
+
|
|
39
40
|
const OPTED_OUT: AutoOkDecision = { is_applied: false, reason: '--no-auto-ok declared' }
|
|
40
41
|
const CROSS_REPOSITORY: AutoOkDecision = {
|
|
41
42
|
is_applied: false,
|
|
42
43
|
reason: 'the Issue is filed to another repository',
|
|
43
44
|
}
|
|
44
|
-
const
|
|
45
|
-
is_applied: false,
|
|
46
|
-
reason: `a ${RELEASE_LABEL} Issue is opted in by a person only`,
|
|
47
|
-
}
|
|
48
|
-
const REQUESTED: AutoOkDecision = {
|
|
45
|
+
const JUDGEMENT: AutoOkDecision = {
|
|
49
46
|
is_applied: false,
|
|
50
|
-
reason:
|
|
47
|
+
reason: `the body declares \`${JUDGEMENT_NEEDED}\``,
|
|
51
48
|
}
|
|
52
|
-
const
|
|
53
|
-
const BRANCH_OPTED_IN: AutoOkDecision = {
|
|
49
|
+
const APPLIED: AutoOkDecision = {
|
|
54
50
|
is_applied: true,
|
|
55
|
-
reason: 'the
|
|
56
|
-
}
|
|
57
|
-
const NOT_OPTED_IN: AutoOkDecision = {
|
|
58
|
-
is_applied: false,
|
|
59
|
-
reason: 'no backlogrun carry record is live and the branch names no auto-ok Issue',
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// What the filing itself declares: `--no-auto-ok` and `--requested`.
|
|
63
|
-
type AutoOkDeclared = Pick<AutoOkSignals, 'is_opted_out' | 'is_requested'>
|
|
64
|
-
type Withholding = AutoOkDeclared & Pick<AutoOkSignals, 'is_release'>
|
|
65
|
-
|
|
66
|
-
// The three signals that withhold `auto-ok` before any other is read, or `undefined` when none holds.
|
|
67
|
-
function withheld(signals: Withholding): AutoOkDecision | undefined {
|
|
68
|
-
if (signals.is_opted_out) return OPTED_OUT
|
|
69
|
-
if (signals.is_release) return RELEASE
|
|
70
|
-
if (signals.is_requested) return REQUESTED
|
|
71
|
-
|
|
72
|
-
return undefined
|
|
51
|
+
reason: 'no exclusion holds and the body declares no judgement is needed',
|
|
73
52
|
}
|
|
74
53
|
|
|
75
|
-
// The
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
54
|
+
// The labels that keep a person in the loop, each with the reason it withholds `auto-ok`. A
|
|
55
|
+
// `breaking-change` declared in the body arrives here as its label, added before the decision.
|
|
56
|
+
const EXCLUDED_LABELS: ReadonlyArray<readonly [string, string]> = [
|
|
57
|
+
[RELEASE_LABEL, 'a release is Tier C'],
|
|
58
|
+
[BREAKING_CHANGE_LABEL, 'a breaking change needs a person to accept the migration'],
|
|
59
|
+
[DEFERRED_LABEL, 'the Issue is deferred'],
|
|
60
|
+
[NEEDS_HUMAN_REVIEW_LABEL, 'a person reviews the change before it lands'],
|
|
61
|
+
[EPIC_LABEL, 'an epic is opted in by a person, and that opts in every descendant'],
|
|
62
|
+
]
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
64
|
+
// The first label that withholds `auto-ok`, or `undefined` when none of them is present.
|
|
65
|
+
function exclusion_of(labels: ReadonlyArray<string>): AutoOkDecision | undefined {
|
|
66
|
+
const found = EXCLUDED_LABELS.find(([label]) => has_label_name(labels, label))
|
|
83
67
|
|
|
84
|
-
return
|
|
85
|
-
}
|
|
68
|
+
if (found === undefined) return undefined
|
|
86
69
|
|
|
87
|
-
|
|
88
|
-
return `auto-ok: ${decision.is_applied ? 'applied' : 'not applied'} — ${decision.reason}`
|
|
70
|
+
return { is_applied: false, reason: `a \`${found[0]}\` Issue — ${found[1]}` }
|
|
89
71
|
}
|
|
90
72
|
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
const
|
|
73
|
+
// `true` / `false` for a declared need, `undefined` when the background declares neither or both.
|
|
74
|
+
function judgement_of(body: string): boolean | undefined {
|
|
75
|
+
const background = markdown_section.section_lines(body, BACKGROUND_HEADING).join('\n')
|
|
76
|
+
const lines = markdown_section.unfenced_lines(background).map((line) => line.trim())
|
|
77
|
+
const is_not_needed = lines.some((line) => line.startsWith(JUDGEMENT_NOT_NEEDED))
|
|
78
|
+
const is_needed = lines.some((line) => line.startsWith(JUDGEMENT_NEEDED))
|
|
94
79
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return run_carry.read_carry(run_carry.carry_path(directory)).kind === 'carried'
|
|
80
|
+
return is_not_needed === is_needed ? undefined : is_needed
|
|
98
81
|
}
|
|
99
82
|
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const issue_number = git_branch.issue_from_branch(await git_command.branch())
|
|
83
|
+
// Why the filing is refused for its declaration, or `undefined` when it declares exactly one answer.
|
|
84
|
+
function declaration_problem(body: string): string | undefined {
|
|
85
|
+
return judgement_of(body) === undefined ? DECLARATION_PROBLEM : undefined
|
|
86
|
+
}
|
|
105
87
|
|
|
106
|
-
|
|
107
|
-
|
|
88
|
+
function decide(filing: AutoOkFiling): AutoOkDecision {
|
|
89
|
+
if (filing.is_opted_out) return OPTED_OUT
|
|
90
|
+
if (filing.is_cross_repository) return CROSS_REPOSITORY
|
|
108
91
|
|
|
109
|
-
return
|
|
92
|
+
return exclusion_of(filing.labels) ?? (judgement_of(filing.body) === false ? APPLIED : JUDGEMENT)
|
|
110
93
|
}
|
|
111
94
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
async function resolve(
|
|
115
|
-
declared: AutoOkDeclared,
|
|
116
|
-
target: string,
|
|
117
|
-
current: string,
|
|
118
|
-
labels: ReadonlyArray<string> = [],
|
|
119
|
-
): Promise<AutoOkDecision> {
|
|
120
|
-
const withholding = { ...declared, is_release: has_label_name(labels, RELEASE_LABEL) }
|
|
121
|
-
const decision = withheld(withholding)
|
|
122
|
-
|
|
123
|
-
if (decision !== undefined) return decision
|
|
124
|
-
if (!issue_file.is_same_repository(target, current)) return CROSS_REPOSITORY
|
|
125
|
-
if (await is_carried()) return CARRIED
|
|
126
|
-
|
|
127
|
-
return decide({ ...withholding, is_carried: false, branch_labels: await branch_labels(current) })
|
|
95
|
+
function line_of(decision: AutoOkDecision): string {
|
|
96
|
+
return `auto-ok: ${decision.is_applied ? 'applied' : 'not applied'} — ${decision.reason}`
|
|
128
97
|
}
|
|
129
98
|
|
|
130
|
-
const issue_auto_ok = { decide,
|
|
99
|
+
const issue_auto_ok = { declaration_problem, decide, exclusion_of, line_of }
|
|
131
100
|
|
|
132
|
-
export type {
|
|
101
|
+
export type { AutoOkDecision, AutoOkFiling }
|
|
133
102
|
export { issue_auto_ok }
|
|
@@ -24,7 +24,7 @@ import { issue_scout_cli } from './issue-scout-cli'
|
|
|
24
24
|
import { issue_wip } from './issue-wip'
|
|
25
25
|
|
|
26
26
|
// `josh issue:file "<title>" --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>]…
|
|
27
|
-
// [--repo <owner/repo>] [--distinct <N,…>] [--over-cap] [--no-auto-ok] [--
|
|
27
|
+
// [--repo <owner/repo>] [--distinct <N,…>] [--over-cap] [--no-auto-ok] [--release]` — file an Issue
|
|
28
28
|
// with every filing step run in order: the third-party refusal, the body
|
|
29
29
|
// lint, the `## Origin` check for another repository, the `auto-ok` decision
|
|
30
30
|
// with the run label it owes, the fold question against the run's earlier
|
|
@@ -37,7 +37,7 @@ const SUCCESS_EXIT_CODE = 0
|
|
|
37
37
|
const FAILURE_EXIT_CODE = 1
|
|
38
38
|
const ARGV_OFFSET = 2
|
|
39
39
|
const USAGE =
|
|
40
|
-
'Usage: josh issue:file "<title>" --body-file <path> --depth <0|1|2> [--route <tier-a|split|interrupt|review-cap>] [--label <name>]… [--repo <owner/repo>] [--distinct <N,…>] [--over-cap] [--no-auto-ok] [--
|
|
40
|
+
'Usage: josh issue:file "<title>" --body-file <path> --depth <0|1|2> [--route <tier-a|split|interrupt|review-cap>] [--label <name>]… [--repo <owner/repo>] [--distinct <N,…>] [--over-cap] [--no-auto-ok] [--release]'
|
|
41
41
|
const UNKNOWN_REPO_MESSAGE =
|
|
42
42
|
'Could not read this repository from `git remote`, so the filing has no repository to compare against — check `gh auth status`.'
|
|
43
43
|
const THIRD_PARTY_MESSAGE =
|
|
@@ -74,10 +74,13 @@ function is_third_party(target: string): boolean {
|
|
|
74
74
|
// the filing may go on to the scout.
|
|
75
75
|
function refusals_of(filing: Filing): ReadonlyArray<string> {
|
|
76
76
|
if (is_third_party(filing.target)) return [THIRD_PARTY_MESSAGE]
|
|
77
|
-
const problems =
|
|
78
|
-
|
|
77
|
+
const problems = [
|
|
78
|
+
...issue_lint_cli.problems(filing.body),
|
|
79
|
+
issue_auto_ok.declaration_problem(filing.body),
|
|
80
|
+
issue_file.origin_problem(filing.body, filing.target, filing.current),
|
|
81
|
+
]
|
|
79
82
|
|
|
80
|
-
return
|
|
83
|
+
return problems.filter((problem) => problem !== undefined).map((problem) => `✖ ${problem}`)
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
function unacknowledged_message(numbers: ReadonlyArray<number>): string {
|
|
@@ -143,18 +146,15 @@ async function is_scout_clear(filing: Filing): Promise<boolean> {
|
|
|
143
146
|
}
|
|
144
147
|
|
|
145
148
|
// Every label the create call carries, or `undefined` when an `auto-ok` filing names neither run label.
|
|
146
|
-
// Decided before the WIP count and the scout, so a refusal costs no listing.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
// Decided before the WIP count and the scout, so a refusal costs no listing. The decision reads the
|
|
150
|
+
// labels the body's declarations add, so a declared breaking change is excluded like its label.
|
|
151
|
+
function labels_of(filing: Filing): ReadonlyArray<string> | undefined {
|
|
152
|
+
const auto_ok = issue_auto_ok.decide({
|
|
149
153
|
is_opted_out: filing.args.is_auto_ok_opted_out,
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
filing.target,
|
|
155
|
-
filing.current,
|
|
156
|
-
filing.args.labels,
|
|
157
|
-
)
|
|
154
|
+
is_cross_repository: !issue_file.is_same_repository(filing.target, filing.current),
|
|
155
|
+
labels: issue_file.labels_of(filing.args, filing.body),
|
|
156
|
+
body: filing.body,
|
|
157
|
+
})
|
|
158
158
|
|
|
159
159
|
console.info(issue_auto_ok.line_of(auto_ok))
|
|
160
160
|
const labels = issue_file.labels_of(filing.args, filing.body, auto_ok.is_applied)
|
|
@@ -271,7 +271,7 @@ async function is_clear(filing: Filing): Promise<boolean> {
|
|
|
271
271
|
|
|
272
272
|
async function file(filing: Filing): Promise<number> {
|
|
273
273
|
if (!is_admitted(filing)) return FAILURE_EXIT_CODE
|
|
274
|
-
const labels =
|
|
274
|
+
const labels = labels_of(filing)
|
|
275
275
|
|
|
276
276
|
if (labels === undefined || !(await is_clear(filing))) return FAILURE_EXIT_CODE
|
|
277
277
|
|
|
@@ -41,9 +41,6 @@ interface FileArguments {
|
|
|
41
41
|
is_over_cap: boolean
|
|
42
42
|
// `--no-auto-ok`: the Issue needs a person's judgement, so `auto-ok` is not applied (`issue-auto-ok.ts`).
|
|
43
43
|
is_auto_ok_opted_out: boolean
|
|
44
|
-
// `--requested`: a person asked for this filing, so `auto-ok` is applied only when a `--label` names
|
|
45
|
-
// it (`issue-auto-ok.ts`).
|
|
46
|
-
is_requested: boolean
|
|
47
44
|
// `--release`: the change reaches a consumer only once published, so the Issue is linked to the
|
|
48
45
|
// repository's release Issue as a blocker (`issue-release-cli.ts`).
|
|
49
46
|
is_release: boolean
|
|
@@ -58,7 +55,6 @@ const OPTIONS = {
|
|
|
58
55
|
distinct: { type: 'string', multiple: true },
|
|
59
56
|
'over-cap': { type: 'boolean' },
|
|
60
57
|
'no-auto-ok': { type: 'boolean' },
|
|
61
|
-
requested: { type: 'boolean' },
|
|
62
58
|
release: { type: 'boolean' },
|
|
63
59
|
} as const
|
|
64
60
|
|
|
@@ -129,7 +125,6 @@ function arguments_of(values: ParsedValues, title: string | undefined): FileArgu
|
|
|
129
125
|
repo: values.repo,
|
|
130
126
|
is_over_cap: values['over-cap'] === true,
|
|
131
127
|
is_auto_ok_opted_out: values['no-auto-ok'] === true,
|
|
132
|
-
is_requested: values.requested === true,
|
|
133
128
|
is_release: values.release === true,
|
|
134
129
|
}
|
|
135
130
|
}
|
|
@@ -151,7 +146,7 @@ function is_undeclared_classification(label: string, body: string): boolean {
|
|
|
151
146
|
|
|
152
147
|
// Every label the filing carries: the depth, the route when there is one, the classification labels
|
|
153
148
|
// the body declares (`issue_classification.labels_for`, which merges case-insensitively), then any
|
|
154
|
-
// extra `--label`, then `auto-ok` when the filing
|
|
149
|
+
// extra `--label`, then `auto-ok` when the filing is judged in (`issue-auto-ok.ts`) and no `--label`
|
|
155
150
|
// already named it. One request applies them all, so no label is a separate step to forget.
|
|
156
151
|
function labels_of(args: FileArguments, body: string, is_auto_ok = false): ReadonlyArray<string> {
|
|
157
152
|
const extra = args.labels.filter((label) => !is_undeclared_classification(label, body))
|
|
@@ -67,9 +67,15 @@ const ALREADY_DONE_LABEL = 'already-done'
|
|
|
67
67
|
// Marks the Issue that tracks a repository's next release. An Issue whose
|
|
68
68
|
// change reaches a consumer only once published is linked to it as a `blocked_by` blocker
|
|
69
69
|
// (`josh issue:release`), so "merged but not yet released" is visible in the backlog. A run applies
|
|
70
|
-
// it; **`auto-ok` never rides on it** — `issue-auto-ok.ts`
|
|
71
|
-
//
|
|
70
|
+
// it; **`auto-ok` never rides on it** — `issue-auto-ok.ts` excludes it, since a release is Tier C —
|
|
71
|
+
// and only a person opts it into unattended execution.
|
|
72
72
|
const RELEASE_LABEL = 'release'
|
|
73
|
+
// A person's mark for work set aside for now; `issue-auto-ok.ts` reads it as an exclusion. Applied by
|
|
74
|
+
// hand and never provisioned, so it is not in `REPOSITORY_LABELS`.
|
|
75
|
+
const DEFERRED_LABEL = 'deferred'
|
|
76
|
+
// Applied to an Issue whose second review round was skipped, so the condition stays auditable
|
|
77
|
+
// (`prompts/review.md` → "When round 2 is skipped entirely, and when it is not").
|
|
78
|
+
const REVIEW_ROUND2_SKIPPED_LABEL = 'review-round2-skipped'
|
|
73
79
|
|
|
74
80
|
// The four labels that mean an open issue must not be handed to a run as it stands: an `epic`
|
|
75
81
|
// tracks a batch and is never run directly (its children are), `in-progress` is already claimed by
|
|
@@ -205,8 +211,11 @@ interface LabelDefinition {
|
|
|
205
211
|
}
|
|
206
212
|
|
|
207
213
|
// What `josh start` provisions on a new repository so the first `kickoff` finds every label a run
|
|
208
|
-
// applies with its intended color. The
|
|
209
|
-
//
|
|
214
|
+
// applies with its intended color. The metadata is the one the workflow documents create each label
|
|
215
|
+
// with. **The labels only a person applies are provisioned too**: a person cannot apply a label the
|
|
216
|
+
// repository does not have, so leaving one out made the first `auto-ok` a manual creation step.
|
|
217
|
+
// `bug` is GitHub's default label, kept because `issue:file` applies it to a bug fix and a
|
|
218
|
+
// repository may have been created without the defaults.
|
|
210
219
|
const WORKFLOW_LABELS: ReadonlyArray<LabelDefinition> = [
|
|
211
220
|
{
|
|
212
221
|
name: EPIC_LABEL,
|
|
@@ -235,6 +244,32 @@ const WORKFLOW_LABELS: ReadonlyArray<LabelDefinition> = [
|
|
|
235
244
|
color: 'fef2c0',
|
|
236
245
|
description: 'Tracks the next release; its blockers are the merged work it publishes',
|
|
237
246
|
},
|
|
247
|
+
{
|
|
248
|
+
name: AUTO_OK_LABEL,
|
|
249
|
+
color: '0e8a16',
|
|
250
|
+
description: 'Opted in to unattended execution outside an epic',
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: NEEDS_DECISION_LABEL,
|
|
254
|
+
color: 'd93f0b',
|
|
255
|
+
description: 'Parked: needs a decision before it can run',
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
name: NEEDS_HUMAN_REVIEW_LABEL,
|
|
259
|
+
color: 'd93f0b',
|
|
260
|
+
description: 'Implement and verify, but stop before committing so a person can look',
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: ALREADY_DONE_LABEL,
|
|
264
|
+
color: '6f42c1',
|
|
265
|
+
description: 'Verified already merged — a person closes it',
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: REVIEW_ROUND2_SKIPPED_LABEL,
|
|
269
|
+
color: 'c5def5',
|
|
270
|
+
description: 'Review round 2 was skipped under the condition in prompts/review.md',
|
|
271
|
+
},
|
|
272
|
+
{ name: BUG_LABEL, color: 'd73a4a', description: "Something isn't working" },
|
|
238
273
|
...FILING_ROUTE_LABELS,
|
|
239
274
|
...DEPTH_LABELS,
|
|
240
275
|
]
|
|
@@ -329,12 +364,6 @@ function depth_label_of(labels: ReadonlyArray<LabelReference> | undefined): stri
|
|
|
329
364
|
// document operates on a label name that does not exist here — a stale or mistyped `labels[]=…`
|
|
330
365
|
// otherwise fails silently at run time. One source, so a label added above joins the scan without a
|
|
331
366
|
// second edit.
|
|
332
|
-
// Applied to an Issue whose second review round was skipped, so the condition stays auditable
|
|
333
|
-
// (`prompts/review.md` → "When round 2 is skipped entirely, and when it is not"). Provisioned inline
|
|
334
|
-
// by the run that applies it rather than through `FILING_ROUTE_LABELS`, but still a managed label the
|
|
335
|
-
// documents operate on, so the label-reference scan has to know it.
|
|
336
|
-
const REVIEW_ROUND2_SKIPPED_LABEL = 'review-round2-skipped'
|
|
337
|
-
|
|
338
367
|
const ALL_LABELS: ReadonlySet<string> = new Set([
|
|
339
368
|
EPIC_LABEL,
|
|
340
369
|
BUG_LABEL,
|
|
@@ -363,6 +392,11 @@ const ALL_LABELS: ReadonlySet<string> = new Set([
|
|
|
363
392
|
IGNORE_FOR_RELEASE_LABEL,
|
|
364
393
|
])
|
|
365
394
|
|
|
395
|
+
// The managed labels `REPOSITORY_LABELS` deliberately does not provision, each with its reason. Every
|
|
396
|
+
// other member of `ALL_LABELS` is provisioned — `issue-labels.test.ts` fails on one that is in
|
|
397
|
+
// neither list, so a label added above cannot silently become one a repository lacks. Empty today.
|
|
398
|
+
const EXEMPT_FROM_PROVISIONING: ReadonlyMap<string, string> = new Map<string, string>()
|
|
399
|
+
|
|
366
400
|
export type { LabelDefinition, ReleaseClassification }
|
|
367
401
|
export {
|
|
368
402
|
ALL_LABELS,
|
|
@@ -371,6 +405,7 @@ export {
|
|
|
371
405
|
BUG_LABEL,
|
|
372
406
|
BUGFIX_LABEL,
|
|
373
407
|
BREAKING_CHANGE_LABEL,
|
|
408
|
+
DEFERRED_LABEL,
|
|
374
409
|
depth_label_of,
|
|
375
410
|
DEPTH_0_LABEL,
|
|
376
411
|
DEPTH_1_LABEL,
|
|
@@ -379,6 +414,7 @@ export {
|
|
|
379
414
|
DEPTH_LABELS,
|
|
380
415
|
ENHANCEMENT_LABEL,
|
|
381
416
|
EPIC_LABEL,
|
|
417
|
+
EXEMPT_FROM_PROVISIONING,
|
|
382
418
|
FILING_ROUTE_LABELS,
|
|
383
419
|
has_any_label,
|
|
384
420
|
has_label_name,
|