@deftai/directive-core 0.79.2 → 0.79.4
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/dist/check/orchestrator.d.ts +4 -0
- package/dist/check/orchestrator.js +9 -1
- package/dist/coverage-hotspots/evaluate.d.ts +49 -0
- package/dist/coverage-hotspots/evaluate.js +262 -0
- package/dist/coverage-hotspots/index.d.ts +3 -0
- package/dist/coverage-hotspots/index.js +3 -0
- package/dist/coverage-hotspots/thresholds.d.ts +5 -0
- package/dist/coverage-hotspots/thresholds.js +48 -0
- package/dist/hooks/dispatcher.d.ts +7 -0
- package/dist/hooks/dispatcher.js +44 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/init-deposit/xbrief-projections.d.ts +7 -0
- package/dist/init-deposit/xbrief-projections.js +29 -1
- package/dist/integration-e2e/bootstrap-cache-module.d.ts +2 -4
- package/dist/integration-e2e/bootstrap-cache-module.js +2 -20
- package/dist/platform/resolve-version.d.ts +2 -6
- package/dist/platform/resolve-version.js +3 -129
- package/dist/pr-merge-readiness/gh.js +13 -5
- package/dist/pr-merge-readiness/test-gh-fixtures.helpers.d.ts +18 -0
- package/dist/pr-merge-readiness/test-gh-fixtures.helpers.js +76 -0
- package/dist/pr-monitor/monitor.js +10 -1
- package/dist/pr-wait-mergeable/cascade.js +8 -1
- package/dist/pr-wait-mergeable/classify.js +5 -1
- package/dist/pr-wait-mergeable/wrappers.js +15 -4
- package/dist/pr-watch/constants.d.ts +15 -0
- package/dist/pr-watch/constants.js +37 -0
- package/dist/pr-watch/index.d.ts +1 -1
- package/dist/pr-watch/index.js +1 -1
- package/dist/pr-watch/main.d.ts +3 -0
- package/dist/pr-watch/main.js +33 -3
- package/dist/pr-watch/probe.js +5 -1
- package/dist/pr-watch/types.d.ts +2 -0
- package/dist/pr-watch/watch.js +17 -1
- package/dist/release/constants.d.ts +5 -0
- package/dist/release/constants.js +14 -2
- package/dist/release/flags.js +16 -0
- package/dist/release/main.js +7 -0
- package/dist/release/pipeline.js +7 -3
- package/dist/release/preflight.js +8 -1
- package/dist/release/skip-ci-incident.d.ts +22 -0
- package/dist/release/skip-ci-incident.js +68 -0
- package/dist/release/types.d.ts +2 -0
- package/dist/release/version.js +68 -32
- package/dist/release-e2e/entrypoint-worker.js +1 -0
- package/dist/release-e2e/entrypoint.js +13 -0
- package/dist/review-monitor/constants.d.ts +14 -0
- package/dist/review-monitor/constants.js +55 -0
- package/dist/review-monitor/index.d.ts +5 -0
- package/dist/review-monitor/index.js +5 -0
- package/dist/review-monitor/record.d.ts +50 -0
- package/dist/review-monitor/record.js +178 -0
- package/dist/review-monitor/tier-detection.d.ts +15 -0
- package/dist/review-monitor/tier-detection.js +61 -0
- package/dist/review-monitor/verify.d.ts +32 -0
- package/dist/review-monitor/verify.js +171 -0
- package/dist/scope/undo.js +12 -2
- package/dist/triage/bootstrap/cache-module.d.ts +25 -0
- package/dist/triage/bootstrap/cache-module.js +39 -0
- package/dist/triage/bootstrap/index.d.ts +1 -0
- package/dist/triage/bootstrap/index.js +7 -82
- package/dist/xbrief-migrate/agents-header.d.ts +0 -11
- package/dist/xbrief-migrate/agents-header.js +10 -1
- package/package.json +7 -3
package/dist/pr-watch/types.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export interface WatchProbe {
|
|
|
13
13
|
readonly hasBlocking: boolean;
|
|
14
14
|
readonly errored: boolean;
|
|
15
15
|
readonly ciFailures: number;
|
|
16
|
+
/** Failed required check identities (name + conclusion), when CI was probed. */
|
|
17
|
+
readonly ciFailedChecks: readonly string[];
|
|
16
18
|
/** All required CI check-runs have a terminal conclusion (none pending). */
|
|
17
19
|
readonly terminalCheckRun: boolean;
|
|
18
20
|
readonly isClean: boolean;
|
package/dist/pr-watch/watch.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defaultRunGh } from "../pr-merge-readiness/gh.js";
|
|
2
|
-
import { DEFAULT_MAX_WAIT_MINUTES, DEFAULT_POLL_SECONDS, DEFAULT_STALL_THRESHOLD, EXIT_CLEAN, EXIT_NEW_P0_P1, EXIT_TERMINAL_ERROR, VERDICT_CLEAN, VERDICT_CONFIG, VERDICT_ERRORED, VERDICT_NEW_P0_P1, VERDICT_PENDING, VERDICT_STALL, VERDICT_TIMEOUT, } from "./constants.js";
|
|
2
|
+
import { DEFAULT_CI_BLOCKED_THRESHOLD, DEFAULT_MAX_WAIT_MINUTES, DEFAULT_POLL_SECONDS, DEFAULT_STALL_THRESHOLD, EXIT_CLEAN, EXIT_NEW_P0_P1, EXIT_TERMINAL_ERROR, VERDICT_CI_BLOCKED, VERDICT_CLEAN, VERDICT_CONFIG, VERDICT_ERRORED, VERDICT_NEW_P0_P1, VERDICT_PENDING, VERDICT_STALL, VERDICT_TIMEOUT, } from "./constants.js";
|
|
3
3
|
import { probeOnce } from "./probe.js";
|
|
4
4
|
const systemMonotonicClock = {
|
|
5
5
|
now() {
|
|
@@ -52,6 +52,7 @@ export function watch(prNumber, repo, options = {}) {
|
|
|
52
52
|
const startedAt = clockFn.now();
|
|
53
53
|
let lastProbe = null;
|
|
54
54
|
let stallStreak = 0;
|
|
55
|
+
let ciBlockedStreak = 0;
|
|
55
56
|
const build = (verdict, exitCode, probe, poll) => ({
|
|
56
57
|
verdict,
|
|
57
58
|
exitCode,
|
|
@@ -79,6 +80,20 @@ export function watch(prNumber, repo, options = {}) {
|
|
|
79
80
|
if (probe.errored) {
|
|
80
81
|
return build(VERDICT_ERRORED, EXIT_TERMINAL_ERROR, probe, poll);
|
|
81
82
|
}
|
|
83
|
+
// #2688: Greptile side satisfied on HEAD but CI red — fail loud toward a
|
|
84
|
+
// fix loop instead of burning max-wait-minutes on idle Greptile polls.
|
|
85
|
+
if (probe.cleanGateHoldout === "ci_failures") {
|
|
86
|
+
ciBlockedStreak += 1;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
ciBlockedStreak = 0;
|
|
90
|
+
}
|
|
91
|
+
if (oneShot && probe.cleanGateHoldout === "ci_failures") {
|
|
92
|
+
return build(VERDICT_CI_BLOCKED, EXIT_TERMINAL_ERROR, probe, poll);
|
|
93
|
+
}
|
|
94
|
+
if (!oneShot && ciBlockedStreak >= DEFAULT_CI_BLOCKED_THRESHOLD) {
|
|
95
|
+
return build(VERDICT_CI_BLOCKED, EXIT_TERMINAL_ERROR, probe, poll);
|
|
96
|
+
}
|
|
82
97
|
// Stall = a review IS present but stuck on a non-HEAD commit; surface it
|
|
83
98
|
// rather than burning the whole cap waiting for a re-review that isn't coming.
|
|
84
99
|
if (probe.found && !probe.shaMatch) {
|
|
@@ -112,6 +127,7 @@ export function watch(prNumber, repo, options = {}) {
|
|
|
112
127
|
hasBlocking: false,
|
|
113
128
|
errored: false,
|
|
114
129
|
ciFailures: 0,
|
|
130
|
+
ciFailedChecks: [],
|
|
115
131
|
terminalCheckRun: false,
|
|
116
132
|
isClean: false,
|
|
117
133
|
cleanGateHoldout: null,
|
|
@@ -20,6 +20,11 @@ export declare const DESTRUCTIVE_GH_GATE_BYPASS_ENV = "DEFT_ALLOW_DESTRUCTIVE_GH
|
|
|
20
20
|
export declare const RELEASE_PREFLIGHT_ENV = "DEFT_RELEASE_PREFLIGHT";
|
|
21
21
|
/** Set only by release Step-5 preflight when --allow-coverage-debt=#N is supplied (#2573). */
|
|
22
22
|
export declare const COVERAGE_DEBT_ENV = "DEFT_ALLOW_COVERAGE_DEBT";
|
|
23
|
+
/** Hard wall-clock cap for release Step 5 `task check` / vitest coverage (#2652). */
|
|
24
|
+
export declare const RELEASE_CHECK_TIMEOUT_MS: number;
|
|
25
|
+
export declare const RELEASE_CHECK_TIMEOUT_MINUTES = 20;
|
|
26
|
+
/** Vitest coverage step cap in GHA CI (mirrors release Step 5 budget, #2652). */
|
|
27
|
+
export declare const CI_VITEST_COVERAGE_TIMEOUT_MINUTES = 20;
|
|
23
28
|
export declare const PYPROJECT_VERSION_LINE_RE: RegExp;
|
|
24
29
|
/** Byte-identical argparse --help from scripts/release.py (Python 3.12). */
|
|
25
30
|
export declare const RELEASE_HELP: string;
|
|
@@ -28,10 +28,16 @@ export const DESTRUCTIVE_GH_GATE_BYPASS_ENV = "DEFT_ALLOW_DESTRUCTIVE_GH_VERBS";
|
|
|
28
28
|
export const RELEASE_PREFLIGHT_ENV = "DEFT_RELEASE_PREFLIGHT";
|
|
29
29
|
/** Set only by release Step-5 preflight when --allow-coverage-debt=#N is supplied (#2573). */
|
|
30
30
|
export const COVERAGE_DEBT_ENV = "DEFT_ALLOW_COVERAGE_DEBT";
|
|
31
|
+
/** Hard wall-clock cap for release Step 5 `task check` / vitest coverage (#2652). */
|
|
32
|
+
export const RELEASE_CHECK_TIMEOUT_MS = 20 * 60 * 1000;
|
|
33
|
+
export const RELEASE_CHECK_TIMEOUT_MINUTES = 20;
|
|
34
|
+
/** Vitest coverage step cap in GHA CI (mirrors release Step 5 budget, #2652). */
|
|
35
|
+
export const CI_VITEST_COVERAGE_TIMEOUT_MINUTES = 20;
|
|
31
36
|
export const PYPROJECT_VERSION_LINE_RE = /version\s*=\s*"[^"]*"/;
|
|
32
37
|
/** Byte-identical argparse --help from scripts/release.py (Python 3.12). */
|
|
33
38
|
export const RELEASE_HELP = "usage: release [-h] [--dry-run] [--skip-tag] [--skip-release] [--allow-dirty]\n" +
|
|
34
39
|
" [--allow-vbrief-drift] [--allow-coverage-debt #N]\n" +
|
|
40
|
+
" [--allow-skip-ci #N]\n" +
|
|
35
41
|
" [--skip-ci] [--skip-build] [--no-draft]\n" +
|
|
36
42
|
" [--repo OWNER/REPO] [--base-branch BRANCH]\n" +
|
|
37
43
|
" [--project-root PATH] [--summary TEXT]\n" +
|
|
@@ -66,11 +72,17 @@ export const RELEASE_HELP = "usage: release [-h] [--dry-run] [--skip-tag] [--ski
|
|
|
66
72
|
" flag cites an operator-owned issue number (#2573).\n" +
|
|
67
73
|
" PowerShell: use --allow-coverage-debt=N (no bare #)\n" +
|
|
68
74
|
' or quote "#N"; unquoted # starts a comment (#2621).\n' +
|
|
69
|
-
" --skip-ci Skip Step
|
|
75
|
+
" --skip-ci Skip Step 5 (task ci:local / task check fallback).\n" +
|
|
70
76
|
" Used by `task release:e2e` to keep wall-clock\n" +
|
|
71
77
|
" manageable inside the auto-created temp repo (CI\n" +
|
|
72
78
|
" semantics are covered by the unit-test suite, not the\n" +
|
|
73
|
-
" e2e rehearsal)
|
|
79
|
+
" e2e rehearsal). Production cuts MUST pass\n" +
|
|
80
|
+
" --allow-skip-ci=#N citing the tracked incident (#2652);\n" +
|
|
81
|
+
" otherwise Step 5 runs with a hard timeout.\n" +
|
|
82
|
+
" --allow-skip-ci #N Acknowledge skipping Step 5 on a production cut (#2652).\n" +
|
|
83
|
+
" Emits a loud WARN — npm ships without vitest coverage.\n" +
|
|
84
|
+
" PowerShell: use --allow-skip-ci=N (no bare #) or quote\n" +
|
|
85
|
+
' "#N"; unquoted # starts a comment (#2621).\n' +
|
|
74
86
|
" --skip-build Skip Step 6 (task build). Used by `task release:e2e`\n" +
|
|
75
87
|
" to keep wall-clock manageable; build artefacts are not\n" +
|
|
76
88
|
" needed for the draft-release verification step.\n" +
|
package/dist/release/flags.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { parseCoverageDebtIssueNumber } from "../vitest-runner/coverage-debt.js";
|
|
2
2
|
import { DEFAULT_BASE_BRANCH, RELEASE_HELP } from "./constants.js";
|
|
3
|
+
import { parseSkipCiIncidentArgv } from "./skip-ci-incident.js";
|
|
3
4
|
export function parseReleaseFlags(args) {
|
|
4
5
|
let help = false;
|
|
5
6
|
let dryRun = false;
|
|
@@ -8,6 +9,8 @@ export function parseReleaseFlags(args) {
|
|
|
8
9
|
let allowDirty = false;
|
|
9
10
|
let allowVbriefDrift = false;
|
|
10
11
|
let allowCoverageDebtIssue = null;
|
|
12
|
+
const skipCiIncident = parseSkipCiIncidentArgv(args);
|
|
13
|
+
const allowSkipCiIssue = skipCiIncident.kind === "valid" ? skipCiIncident.issue : null;
|
|
11
14
|
let skipCi = false;
|
|
12
15
|
let skipBuild = false;
|
|
13
16
|
let draft = true;
|
|
@@ -71,6 +74,15 @@ export function parseReleaseFlags(args) {
|
|
|
71
74
|
else if (token === "--skip-ci") {
|
|
72
75
|
skipCi = true;
|
|
73
76
|
}
|
|
77
|
+
else if (token === "--allow-skip-ci") {
|
|
78
|
+
// Value consumed by parseSkipCiIncidentArgv above; advance past it here.
|
|
79
|
+
const value = takeValue(token, i);
|
|
80
|
+
if (value !== null)
|
|
81
|
+
i += 1;
|
|
82
|
+
}
|
|
83
|
+
else if (token.startsWith("--allow-skip-ci=")) {
|
|
84
|
+
// Value consumed by parseSkipCiIncidentArgv above.
|
|
85
|
+
}
|
|
74
86
|
else if (token === "--skip-build") {
|
|
75
87
|
skipBuild = true;
|
|
76
88
|
}
|
|
@@ -132,6 +144,9 @@ export function parseReleaseFlags(args) {
|
|
|
132
144
|
}
|
|
133
145
|
i += 1;
|
|
134
146
|
}
|
|
147
|
+
if (skipCiIncident.kind === "invalid") {
|
|
148
|
+
unknown.push(`--allow-skip-ci (${skipCiIncident.reason})`);
|
|
149
|
+
}
|
|
135
150
|
return {
|
|
136
151
|
help,
|
|
137
152
|
version,
|
|
@@ -144,6 +159,7 @@ export function parseReleaseFlags(args) {
|
|
|
144
159
|
allowDirty,
|
|
145
160
|
allowVbriefDrift,
|
|
146
161
|
allowCoverageDebtIssue,
|
|
162
|
+
allowSkipCiIssue,
|
|
147
163
|
skipCi,
|
|
148
164
|
skipBuild,
|
|
149
165
|
draft,
|
package/dist/release/main.js
CHANGED
|
@@ -2,6 +2,7 @@ import { EXIT_CONFIG_ERROR } from "./constants.js";
|
|
|
2
2
|
import { formatReleaseHelp, parseReleaseFlags } from "./flags.js";
|
|
3
3
|
import { resolveProjectRoot, resolveRepo } from "./paths.js";
|
|
4
4
|
import { runPipeline } from "./pipeline.js";
|
|
5
|
+
import { validateSkipCiIncident } from "./skip-ci-incident.js";
|
|
5
6
|
import { validateVersion } from "./version.js";
|
|
6
7
|
export function cmdRelease(args, seams = {}) {
|
|
7
8
|
const flags = parseReleaseFlags(args);
|
|
@@ -27,6 +28,11 @@ export function cmdRelease(args, seams = {}) {
|
|
|
27
28
|
}
|
|
28
29
|
const projectRoot = resolveProjectRoot(flags.projectRoot);
|
|
29
30
|
const repo = resolveRepo(flags.repo, projectRoot, seams);
|
|
31
|
+
const skipCiGate = validateSkipCiIncident(flags.skipCi, flags.allowSkipCiIssue, process.env);
|
|
32
|
+
if (skipCiGate.kind === "invalid") {
|
|
33
|
+
process.stderr.write(`release: error: ${skipCiGate.reason}\n`);
|
|
34
|
+
return EXIT_CONFIG_ERROR;
|
|
35
|
+
}
|
|
30
36
|
const config = {
|
|
31
37
|
version: flags.version,
|
|
32
38
|
repo,
|
|
@@ -42,6 +48,7 @@ export function cmdRelease(args, seams = {}) {
|
|
|
42
48
|
summary: flags.summary,
|
|
43
49
|
allowVbriefDrift: flags.allowVbriefDrift,
|
|
44
50
|
allowCoverageDebtIssue: flags.allowCoverageDebtIssue,
|
|
51
|
+
allowSkipCiIssue: flags.allowSkipCiIssue,
|
|
45
52
|
};
|
|
46
53
|
return runPipeline(config, seams);
|
|
47
54
|
}
|
package/dist/release/pipeline.js
CHANGED
|
@@ -2,12 +2,13 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { assertProjectionContained } from "../fs/projection-containment.js";
|
|
4
4
|
import { prependUpgradeBanner, promoteChangelog, sectionForVersion } from "./changelog.js";
|
|
5
|
-
import { EXIT_CONFIG_ERROR, EXIT_OK, EXIT_VIOLATION, RELEASE_ARTIFACTS, TOTAL_STEPS, VERIFY_DRAFT_INTERVAL_SECONDS, VERIFY_DRAFT_MAX_ATTEMPTS, } from "./constants.js";
|
|
5
|
+
import { EXIT_CONFIG_ERROR, EXIT_OK, EXIT_VIOLATION, RELEASE_ARTIFACTS, RELEASE_CHECK_TIMEOUT_MINUTES, TOTAL_STEPS, VERIFY_DRAFT_INTERVAL_SECONDS, VERIFY_DRAFT_MAX_ATTEMPTS, } from "./constants.js";
|
|
6
6
|
import { checkTagAvailable, createGithubRelease, readTextFile, verifyReleaseDraft } from "./gh.js";
|
|
7
7
|
import { checkGitClean, commitReleaseArtifacts, createTag, currentBranch, pushRelease, releaseCommitSubject, } from "./git.js";
|
|
8
8
|
import { checkVbriefLifecycleSyncNative, refreshRoadmapNative, runBuildNative, } from "./native-steps.js";
|
|
9
9
|
import { todayIso } from "./paths.js";
|
|
10
10
|
import { runReleaseCheck } from "./preflight.js";
|
|
11
|
+
import { formatSkipCiIncidentWarning } from "./skip-ci-incident.js";
|
|
11
12
|
import { isPrereleaseTag } from "./version.js";
|
|
12
13
|
export function emit(step, label, status, target = process.stderr) {
|
|
13
14
|
target.write(`[${step}/${TOTAL_STEPS}] ${label}... ${status}\n`);
|
|
@@ -108,13 +109,16 @@ export function runPipeline(config, seams = {}) {
|
|
|
108
109
|
// golden-diff release-parity gate stays green until the oracle is retired.
|
|
109
110
|
label = "Pre-flight CI (task ci:local | fallback task check)";
|
|
110
111
|
if (config.skipCi) {
|
|
112
|
+
if (config.allowSkipCiIssue !== null && config.allowSkipCiIssue > 0) {
|
|
113
|
+
process.stderr.write(formatSkipCiIncidentWarning(config.allowSkipCiIssue));
|
|
114
|
+
}
|
|
111
115
|
emit(5, label, "SKIP (--skip-ci)");
|
|
112
116
|
}
|
|
113
117
|
else if (config.dryRun) {
|
|
114
118
|
const debtNote = config.allowCoverageDebtIssue !== null
|
|
115
119
|
? `; would pass --allow-coverage-debt=#${config.allowCoverageDebtIssue} to task check`
|
|
116
120
|
: "";
|
|
117
|
-
emit(5, label, `DRYRUN (would run task ci:local with task check fallback${debtNote})`);
|
|
121
|
+
emit(5, label, `DRYRUN (would run task ci:local with task check fallback${debtNote}; hard timeout ${RELEASE_CHECK_TIMEOUT_MINUTES}m)`);
|
|
118
122
|
}
|
|
119
123
|
else {
|
|
120
124
|
const [ok, reason] = runCiFn(projectRoot, config.allowCoverageDebtIssue);
|
|
@@ -128,7 +132,7 @@ export function runPipeline(config, seams = {}) {
|
|
|
128
132
|
const debtHint = config.allowCoverageDebtIssue === null
|
|
129
133
|
? "; pass --allow-coverage-debt=#N only after operator review"
|
|
130
134
|
: "";
|
|
131
|
-
emit(5, label, `FAIL (${reason}${debtHint})`);
|
|
135
|
+
emit(5, label, `FAIL (${reason}${debtHint}; Step 5 hard timeout is ${RELEASE_CHECK_TIMEOUT_MINUTES}m — cancel hung vitest and see docs/RELEASING.md § Vitest coverage hang recovery)`);
|
|
132
136
|
return EXIT_VIOLATION;
|
|
133
137
|
}
|
|
134
138
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* dispatches `check:framework-source`.
|
|
9
9
|
*/
|
|
10
10
|
import { dispatchTaskCheck } from "../check/orchestrator.js";
|
|
11
|
-
import { COVERAGE_DEBT_ENV, RELEASE_PREFLIGHT_ENV } from "./constants.js";
|
|
11
|
+
import { COVERAGE_DEBT_ENV, RELEASE_CHECK_TIMEOUT_MS, RELEASE_PREFLIGHT_ENV } from "./constants.js";
|
|
12
12
|
import { releaseSubprocessEnv } from "./git.js";
|
|
13
13
|
/** Step-5-only env: branch bypass plus release pre-flight cache staleness tolerance (#2386). */
|
|
14
14
|
export function releaseCheckEnv(options = {}) {
|
|
@@ -40,6 +40,7 @@ export function runReleaseCheck(projectRoot, seams = {}, allowCoverageDebtIssue
|
|
|
40
40
|
const dispatch = seams.dispatchCheck ?? dispatchTaskCheck;
|
|
41
41
|
const checkSeams = {
|
|
42
42
|
...seams.checkSeams,
|
|
43
|
+
timeoutMs: seams.checkSeams?.timeoutMs ?? RELEASE_CHECK_TIMEOUT_MS,
|
|
43
44
|
env: releaseCheckEnv({
|
|
44
45
|
base: seams.checkSeams?.env ?? process.env,
|
|
45
46
|
allowCoverageDebtIssue,
|
|
@@ -49,6 +50,12 @@ export function runReleaseCheck(projectRoot, seams = {}, allowCoverageDebtIssue
|
|
|
49
50
|
if (code === 0) {
|
|
50
51
|
return [true, "ran native TypeScript task check"];
|
|
51
52
|
}
|
|
53
|
+
if (code === 124) {
|
|
54
|
+
return [
|
|
55
|
+
false,
|
|
56
|
+
`task check timed out after ${RELEASE_CHECK_TIMEOUT_MS / 60_000}m (vitest coverage hang — see docs/RELEASING.md)`,
|
|
57
|
+
];
|
|
58
|
+
}
|
|
52
59
|
return [false, `task check failed (exit ${code})`];
|
|
53
60
|
}
|
|
54
61
|
//# sourceMappingURL=preflight.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Parse `#2652`, `2652`, or bare numeric strings for skip-ci incident citation. */
|
|
2
|
+
export declare function parseSkipCiIncidentIssueNumber(raw: string): number | null;
|
|
3
|
+
export type SkipCiIncidentResolution = {
|
|
4
|
+
readonly kind: "none";
|
|
5
|
+
} | {
|
|
6
|
+
readonly kind: "valid";
|
|
7
|
+
readonly issue: number;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: "invalid";
|
|
10
|
+
readonly reason: string;
|
|
11
|
+
};
|
|
12
|
+
/** Set by `task release:e2e` worker subprocesses — permits `--skip-ci` without issue citation. */
|
|
13
|
+
export declare const RELEASE_E2E_ENV = "DEFT_RELEASE_E2E";
|
|
14
|
+
export declare function parseSkipCiIncidentArgv(argv: readonly string[]): SkipCiIncidentResolution;
|
|
15
|
+
/**
|
|
16
|
+
* Production `--skip-ci` is an incident (#2652): require `--allow-skip-ci=#N` or
|
|
17
|
+
* run inside `task release:e2e` (`DEFT_RELEASE_E2E=1`).
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateSkipCiIncident(skipCi: boolean, allowSkipCiIssue: number | null, env?: NodeJS.ProcessEnv): SkipCiIncidentResolution;
|
|
20
|
+
/** Loud stderr banner when Step 5 is skipped with operator acknowledgment (#2652). */
|
|
21
|
+
export declare function formatSkipCiIncidentWarning(issue: number): string;
|
|
22
|
+
//# sourceMappingURL=skip-ci-incident.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Parse `#2652`, `2652`, or bare numeric strings for skip-ci incident citation. */
|
|
2
|
+
export function parseSkipCiIncidentIssueNumber(raw) {
|
|
3
|
+
const trimmed = raw.trim();
|
|
4
|
+
if (!trimmed)
|
|
5
|
+
return null;
|
|
6
|
+
const normalized = trimmed.startsWith("#") ? trimmed.slice(1) : trimmed;
|
|
7
|
+
if (!/^\d+$/.test(normalized))
|
|
8
|
+
return null;
|
|
9
|
+
const issue = Number.parseInt(normalized, 10);
|
|
10
|
+
return Number.isFinite(issue) && issue > 0 ? issue : null;
|
|
11
|
+
}
|
|
12
|
+
const SKIP_CI_FLAG = "--allow-skip-ci";
|
|
13
|
+
/** Set by `task release:e2e` worker subprocesses — permits `--skip-ci` without issue citation. */
|
|
14
|
+
export const RELEASE_E2E_ENV = "DEFT_RELEASE_E2E";
|
|
15
|
+
export function parseSkipCiIncidentArgv(argv) {
|
|
16
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
17
|
+
const token = argv[i] ?? "";
|
|
18
|
+
if (token === SKIP_CI_FLAG) {
|
|
19
|
+
const next = argv[i + 1];
|
|
20
|
+
if (next === undefined || next.startsWith("-")) {
|
|
21
|
+
return { kind: "invalid", reason: `${SKIP_CI_FLAG} requires an issue number (#N)` };
|
|
22
|
+
}
|
|
23
|
+
const issue = parseSkipCiIncidentIssueNumber(next);
|
|
24
|
+
return issue === null
|
|
25
|
+
? { kind: "invalid", reason: `${SKIP_CI_FLAG} value must be #N or N` }
|
|
26
|
+
: { kind: "valid", issue };
|
|
27
|
+
}
|
|
28
|
+
if (token.startsWith(`${SKIP_CI_FLAG}=`)) {
|
|
29
|
+
const value = token.slice(SKIP_CI_FLAG.length + 1);
|
|
30
|
+
const issue = parseSkipCiIncidentIssueNumber(value);
|
|
31
|
+
return issue === null
|
|
32
|
+
? { kind: "invalid", reason: `${SKIP_CI_FLAG}= value must be #N or N` }
|
|
33
|
+
: { kind: "valid", issue };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { kind: "none" };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Production `--skip-ci` is an incident (#2652): require `--allow-skip-ci=#N` or
|
|
40
|
+
* run inside `task release:e2e` (`DEFT_RELEASE_E2E=1`).
|
|
41
|
+
*/
|
|
42
|
+
export function validateSkipCiIncident(skipCi, allowSkipCiIssue, env = process.env) {
|
|
43
|
+
if (!skipCi) {
|
|
44
|
+
return { kind: "none" };
|
|
45
|
+
}
|
|
46
|
+
if (allowSkipCiIssue !== null) {
|
|
47
|
+
return { kind: "valid", issue: allowSkipCiIssue };
|
|
48
|
+
}
|
|
49
|
+
if (env[RELEASE_E2E_ENV] === "1") {
|
|
50
|
+
return { kind: "valid", issue: 0 };
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
kind: "invalid",
|
|
54
|
+
reason: "production --skip-ci skips Step 5 vitest coverage and ships untested npm builds (#2652). " +
|
|
55
|
+
"Pass --allow-skip-ci=#N citing the tracked incident after operator review, " +
|
|
56
|
+
"or use `task release:e2e` for rehearsal-only skips.",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Loud stderr banner when Step 5 is skipped with operator acknowledgment (#2652). */
|
|
60
|
+
export function formatSkipCiIncidentWarning(issue) {
|
|
61
|
+
const cite = issue > 0 ? `#${issue}` : "release:e2e rehearsal";
|
|
62
|
+
return (`\n` +
|
|
63
|
+
`*** WARNING: release Step 5 CI/coverage SKIPPED (--skip-ci) ***\n` +
|
|
64
|
+
`*** This cut will NOT be validated by vitest coverage / task check. ***\n` +
|
|
65
|
+
`*** Incident citation: ${cite} — npm publish proceeds UNTESTED (#2652). ***\n` +
|
|
66
|
+
`*** Next production patch MUST cut without --skip-ci once the hang is fixed. ***\n\n`);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=skip-ci-incident.js.map
|
package/dist/release/types.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface ReleaseConfig {
|
|
|
13
13
|
readonly summary: string | null;
|
|
14
14
|
readonly allowVbriefDrift: boolean;
|
|
15
15
|
readonly allowCoverageDebtIssue: number | null;
|
|
16
|
+
readonly allowSkipCiIssue: number | null;
|
|
16
17
|
}
|
|
17
18
|
export interface ReleaseFlags {
|
|
18
19
|
readonly help: boolean;
|
|
@@ -30,6 +31,7 @@ export interface ReleaseFlags {
|
|
|
30
31
|
readonly draft: boolean;
|
|
31
32
|
readonly summary: string | null;
|
|
32
33
|
readonly allowCoverageDebtIssue: number | null;
|
|
34
|
+
readonly allowSkipCiIssue: number | null;
|
|
33
35
|
readonly unknown: readonly string[];
|
|
34
36
|
}
|
|
35
37
|
export interface SpawnResult {
|
package/dist/release/version.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const PEP440_TAG_RE = /^v?(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<kind>rc|alpha|beta|test)\.(?<num>\d+))?$/;
|
|
2
1
|
const PRE_KIND_MAP = {
|
|
3
2
|
alpha: "a",
|
|
4
3
|
beta: "b",
|
|
@@ -17,6 +16,55 @@ export class NonPublishableVersionError extends Error {
|
|
|
17
16
|
this.name = "NonPublishableVersionError";
|
|
18
17
|
}
|
|
19
18
|
}
|
|
19
|
+
/** Parse `[v]X.Y.Z[-(rc|alpha|beta|test).N]` via linear scan. */
|
|
20
|
+
function parseReleaseTag(version) {
|
|
21
|
+
let i = 0;
|
|
22
|
+
if (version[i] === "v" || version[i] === "V")
|
|
23
|
+
i += 1;
|
|
24
|
+
const readInt = () => {
|
|
25
|
+
const ch = version[i] ?? "";
|
|
26
|
+
if (i >= version.length || ch < "0" || ch > "9")
|
|
27
|
+
return null;
|
|
28
|
+
let n = 0;
|
|
29
|
+
while (i < version.length) {
|
|
30
|
+
const digit = version[i] ?? "";
|
|
31
|
+
if (digit < "0" || digit > "9")
|
|
32
|
+
break;
|
|
33
|
+
n = n * 10 + Number(digit);
|
|
34
|
+
i += 1;
|
|
35
|
+
}
|
|
36
|
+
return n;
|
|
37
|
+
};
|
|
38
|
+
const major = readInt();
|
|
39
|
+
if (major === null || version[i] !== ".")
|
|
40
|
+
return null;
|
|
41
|
+
i += 1;
|
|
42
|
+
const minor = readInt();
|
|
43
|
+
if (minor === null || version[i] !== ".")
|
|
44
|
+
return null;
|
|
45
|
+
i += 1;
|
|
46
|
+
const patch = readInt();
|
|
47
|
+
if (patch === null)
|
|
48
|
+
return null;
|
|
49
|
+
if (i >= version.length)
|
|
50
|
+
return { major, minor, patch, kind: null, num: null };
|
|
51
|
+
if (version[i] !== "-")
|
|
52
|
+
return null;
|
|
53
|
+
i += 1;
|
|
54
|
+
const kindStart = i;
|
|
55
|
+
while (i < version.length && version[i] !== ".")
|
|
56
|
+
i += 1;
|
|
57
|
+
if (i >= version.length || version[i] !== ".")
|
|
58
|
+
return null;
|
|
59
|
+
const kind = version.slice(kindStart, i);
|
|
60
|
+
if (!["rc", "alpha", "beta", "test"].includes(kind))
|
|
61
|
+
return null;
|
|
62
|
+
i += 1;
|
|
63
|
+
const num = readInt();
|
|
64
|
+
if (num === null || i !== version.length)
|
|
65
|
+
return null;
|
|
66
|
+
return { major, minor, patch, kind, num };
|
|
67
|
+
}
|
|
20
68
|
/** Raise Error when version does not match strict X.Y.Z semver. */
|
|
21
69
|
export function validateVersion(version) {
|
|
22
70
|
if (!/^\d+\.\d+\.\d+$/.test(version)) {
|
|
@@ -27,7 +75,7 @@ export function validateVersion(version) {
|
|
|
27
75
|
/** Return true when version carries a SemVer pre-release suffix (#425). */
|
|
28
76
|
export function isPrereleaseTag(version) {
|
|
29
77
|
let candidate = version.trim();
|
|
30
|
-
if (candidate.startsWith("v")) {
|
|
78
|
+
if (candidate.startsWith("v") || candidate.startsWith("V")) {
|
|
31
79
|
candidate = candidate.slice(1);
|
|
32
80
|
}
|
|
33
81
|
return candidate.includes("-");
|
|
@@ -41,32 +89,26 @@ export function toPep440(version) {
|
|
|
41
89
|
if (!candidate) {
|
|
42
90
|
throw new Error("version must be a non-empty string");
|
|
43
91
|
}
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
92
|
+
const parsed = parseReleaseTag(candidate);
|
|
93
|
+
if (parsed === null) {
|
|
46
94
|
throw new Error(`Cannot normalize '${candidate}' to PEP 440: expected ` +
|
|
47
95
|
"[v]X.Y.Z or [v]X.Y.Z-(rc|alpha|beta|test).N");
|
|
48
96
|
}
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const patch = Number(match.groups.patch);
|
|
52
|
-
const base = `${major}.${minor}.${patch}`;
|
|
53
|
-
const kind = match.groups.kind;
|
|
54
|
-
if (kind === undefined) {
|
|
97
|
+
const base = `${parsed.major}.${parsed.minor}.${parsed.patch}`;
|
|
98
|
+
if (parsed.kind === null)
|
|
55
99
|
return base;
|
|
56
|
-
|
|
57
|
-
if (NON_PUBLISHABLE_KINDS.has(kind)) {
|
|
100
|
+
if (NON_PUBLISHABLE_KINDS.has(parsed.kind)) {
|
|
58
101
|
throw new NonPublishableVersionError(`Version '${candidate}' carries non-publishable pre-release ` +
|
|
59
|
-
`tag '${kind}'.${
|
|
102
|
+
`tag '${parsed.kind}'.${parsed.num} -- release pipeline MUST ` +
|
|
60
103
|
"skip pyproject.toml [project].version sync for this tag.");
|
|
61
104
|
}
|
|
62
|
-
const pepKind = PRE_KIND_MAP[kind];
|
|
105
|
+
const pepKind = PRE_KIND_MAP[parsed.kind];
|
|
63
106
|
if (pepKind === undefined) {
|
|
64
|
-
throw new Error(`Unmapped pre-release kind '${kind}' for version '${candidate}'; ` +
|
|
65
|
-
"add it to
|
|
66
|
-
"
|
|
107
|
+
throw new Error(`Unmapped pre-release kind '${parsed.kind}' for version '${candidate}'; ` +
|
|
108
|
+
"add it to PRE_KIND_MAP or NON_PUBLISHABLE_KINDS to keep the parser " +
|
|
109
|
+
"in lockstep with the publishability classifier.");
|
|
67
110
|
}
|
|
68
|
-
|
|
69
|
-
return `${base}${pepKind}${pepNum}`;
|
|
111
|
+
return `${base}${pepKind}${parsed.num}`;
|
|
70
112
|
}
|
|
71
113
|
export function isPublishable(version) {
|
|
72
114
|
try {
|
|
@@ -79,25 +121,19 @@ export function isPublishable(version) {
|
|
|
79
121
|
}
|
|
80
122
|
function publishableVersionSortKey(version) {
|
|
81
123
|
const candidate = version.trim();
|
|
82
|
-
const
|
|
83
|
-
if (
|
|
84
|
-
throw new Error(`Cannot compare '${candidate}': expected
|
|
124
|
+
const parsed = parseReleaseTag(candidate);
|
|
125
|
+
if (parsed === null) {
|
|
126
|
+
throw new Error(`Cannot compare '${candidate}': expected [v]X.Y.Z or [v]X.Y.Z-(rc|alpha|beta).N`);
|
|
85
127
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
throw new NonPublishableVersionError(`Version '${candidate}' carries non-publishable pre-release tag '${kind}'.${match.groups.num}.`);
|
|
128
|
+
if (parsed.kind !== null && NON_PUBLISHABLE_KINDS.has(parsed.kind)) {
|
|
129
|
+
throw new NonPublishableVersionError(`Version '${candidate}' carries non-publishable pre-release tag '${parsed.kind}'.${parsed.num}.`);
|
|
89
130
|
}
|
|
131
|
+
const kind = parsed.kind ?? "";
|
|
90
132
|
const rank = PRERELEASE_RANK[kind];
|
|
91
133
|
if (rank === undefined) {
|
|
92
134
|
throw new Error(`Cannot compare '${candidate}': unsupported pre-release kind '${kind}'.`);
|
|
93
135
|
}
|
|
94
|
-
return [
|
|
95
|
-
Number(match.groups.major),
|
|
96
|
-
Number(match.groups.minor),
|
|
97
|
-
Number(match.groups.patch),
|
|
98
|
-
rank,
|
|
99
|
-
Number(match.groups.num ?? 0),
|
|
100
|
-
];
|
|
136
|
+
return [parsed.major, parsed.minor, parsed.patch, rank, parsed.num ?? 0];
|
|
101
137
|
}
|
|
102
138
|
/** Compare two publishable Deft release versions using stable/prerelease ordering. */
|
|
103
139
|
export function comparePublishableVersions(left, right) {
|
|
@@ -2,6 +2,7 @@ import { cmdRelease } from "../release/main.js";
|
|
|
2
2
|
import { rollbackMain } from "./rollback-bridge.js";
|
|
3
3
|
export function runWorkerEntrypoint(data) {
|
|
4
4
|
process.env.DEFT_PROJECT_ROOT = data.cloneDir;
|
|
5
|
+
process.env.DEFT_RELEASE_E2E = "1";
|
|
5
6
|
const stdoutChunks = [];
|
|
6
7
|
const stderrChunks = [];
|
|
7
8
|
const prevStdout = process.stdout.write.bind(process.stdout);
|
|
@@ -3,9 +3,11 @@ import { sep } from "node:path";
|
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { MessageChannel, receiveMessageOnPort, Worker } from "node:worker_threads";
|
|
5
5
|
import { cmdRelease } from "../release/main.js";
|
|
6
|
+
import { RELEASE_E2E_ENV } from "../release/skip-ci-incident.js";
|
|
6
7
|
import { ENTRYPOINT_TIMEOUT_EXIT_CODE, EXIT_VIOLATION, RELEASE_ENTRYPOINT_TIMEOUT_SECONDS, ROLLBACK_ENTRYPOINT_TIMEOUT_SECONDS, } from "./constants.js";
|
|
7
8
|
import { rollbackMain } from "./rollback-bridge.js";
|
|
8
9
|
let activeRestoreOwner = null;
|
|
10
|
+
let priorReleaseE2eEnv;
|
|
9
11
|
/** @internal Test hook for restore-owner branch coverage. */
|
|
10
12
|
export function restoreProcessStateForTest(restoreOwner, oldCwd, oldProjectRoot) {
|
|
11
13
|
restoreProcessState(restoreOwner, oldCwd, oldProjectRoot);
|
|
@@ -22,9 +24,18 @@ function restoreProcessState(restoreOwner, oldCwd, oldProjectRoot) {
|
|
|
22
24
|
else {
|
|
23
25
|
process.env.DEFT_PROJECT_ROOT = oldProjectRoot;
|
|
24
26
|
}
|
|
27
|
+
if (priorReleaseE2eEnv === undefined) {
|
|
28
|
+
delete process.env[RELEASE_E2E_ENV];
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
process.env[RELEASE_E2E_ENV] = priorReleaseE2eEnv;
|
|
32
|
+
}
|
|
33
|
+
priorReleaseE2eEnv = undefined;
|
|
25
34
|
}
|
|
26
35
|
function activateProcessState(restoreOwner, cloneDir) {
|
|
27
36
|
activeRestoreOwner = restoreOwner;
|
|
37
|
+
priorReleaseE2eEnv = process.env[RELEASE_E2E_ENV];
|
|
38
|
+
process.env[RELEASE_E2E_ENV] = "1";
|
|
28
39
|
process.env.DEFT_PROJECT_ROOT = cloneDir;
|
|
29
40
|
mkdirSync(cloneDir, { recursive: true });
|
|
30
41
|
process.chdir(cloneDir);
|
|
@@ -223,6 +234,8 @@ export function defaultRollbackEntrypoint(argv) {
|
|
|
223
234
|
return rollbackMain(argv);
|
|
224
235
|
}
|
|
225
236
|
export function dispatchTaskRelease(cloneDir, version, repo, seams = {}) {
|
|
237
|
+
// Rehearsal --skip-ci is permitted via DEFT_RELEASE_E2E (set in activateProcessState /
|
|
238
|
+
// worker), not a fake production --allow-skip-ci citation (#2652 Greptile).
|
|
226
239
|
const argv = [version, "--repo", repo, "--skip-ci", "--skip-build", "--allow-vbrief-drift"];
|
|
227
240
|
if (seams.releaseEntrypoint) {
|
|
228
241
|
const code = seams.releaseEntrypoint(argv);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Deterministic review-monitor gate (#2655). Three-state exit contract. */
|
|
2
|
+
export declare const EXIT_READY = 0;
|
|
3
|
+
export declare const EXIT_NOT_READY = 1;
|
|
4
|
+
export declare const EXIT_CONFIG_ERROR = 2;
|
|
5
|
+
export declare const SCHEMA_VERSION = 1;
|
|
6
|
+
export declare const REVIEW_MONITOR_FILENAME = "review-monitor.json";
|
|
7
|
+
export declare const REVIEW_MONITOR_RELPATH: readonly [".deft", "review-monitor.json"];
|
|
8
|
+
export declare const MONITORING_TIER_1 = 1;
|
|
9
|
+
export declare const MONITORING_TIER_2 = 2;
|
|
10
|
+
export declare const MONITORING_TIER_3 = 3;
|
|
11
|
+
export declare const DEFAULT_STALE_MINUTES = 30;
|
|
12
|
+
export declare const REVIEW_MONITOR_HELP: string;
|
|
13
|
+
export declare const REGISTER_HELP: string;
|
|
14
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Deterministic review-monitor gate (#2655). Three-state exit contract. */
|
|
2
|
+
export const EXIT_READY = 0;
|
|
3
|
+
export const EXIT_NOT_READY = 1;
|
|
4
|
+
export const EXIT_CONFIG_ERROR = 2;
|
|
5
|
+
export const SCHEMA_VERSION = 1;
|
|
6
|
+
export const REVIEW_MONITOR_FILENAME = "review-monitor.json";
|
|
7
|
+
export const REVIEW_MONITOR_RELPATH = [".deft", REVIEW_MONITOR_FILENAME];
|
|
8
|
+
export const MONITORING_TIER_1 = 1;
|
|
9
|
+
export const MONITORING_TIER_2 = 2;
|
|
10
|
+
export const MONITORING_TIER_3 = 3;
|
|
11
|
+
export const DEFAULT_STALE_MINUTES = 30;
|
|
12
|
+
export const REVIEW_MONITOR_HELP = "usage: task verify:review-monitor -- --pr <N> [options]\n" +
|
|
13
|
+
"\n" +
|
|
14
|
+
"Fail-closed gate: when Tier 1 (sub-agent primitive available), require a\n" +
|
|
15
|
+
"recorded active review-monitor before the parent may yield, Approach-3\n" +
|
|
16
|
+
"sleep-poll, or claim review ownership (#2655).\n" +
|
|
17
|
+
"\n" +
|
|
18
|
+
"options:\n" +
|
|
19
|
+
" -h, --help Show this help and exit 0\n" +
|
|
20
|
+
" --pr N Pull request number (required unless --help)\n" +
|
|
21
|
+
" --repo OWNER/REPO Repository (optional audit field)\n" +
|
|
22
|
+
" --head-sha SHA Expected HEAD SHA (optional freshness check)\n" +
|
|
23
|
+
" --project-root PATH Project root (default: cwd)\n" +
|
|
24
|
+
" --call-site SITE solo | swarm-phase5-6 | swarm-phase6-cascade\n" +
|
|
25
|
+
" --approach3 Assert Approach 3 (blocking poll) intent\n" +
|
|
26
|
+
" --approach3-warned User acknowledged Approach 3 warning (Tier 3 only)\n" +
|
|
27
|
+
" --json Emit structured JSON on stdout\n" +
|
|
28
|
+
"\n" +
|
|
29
|
+
"exit codes:\n" +
|
|
30
|
+
" 0 READY Tier 1 monitor recorded, or Tier 3 Approach 3 with warning ack\n" +
|
|
31
|
+
" 1 NOT READY Tier 1 without monitor, or Approach 3 blocked on Tier 1\n" +
|
|
32
|
+
" 2 CONFIG Usage / path / unreadable state error\n" +
|
|
33
|
+
"\n" +
|
|
34
|
+
"Register a monitor after spawning Approach 1:\n" +
|
|
35
|
+
" task review-monitor:register -- --pr <N> --monitor-agent-id <id> \\\n" +
|
|
36
|
+
" --platform-primitive cursor-task|spawn_subagent|start_agent \\\n" +
|
|
37
|
+
" [--head-sha SHA] [--repo OWNER/REPO]\n";
|
|
38
|
+
export const REGISTER_HELP = "usage: task review-monitor:register -- --pr <N> --monitor-agent-id <id> \\\n" +
|
|
39
|
+
" --platform-primitive <primitive> [options]\n" +
|
|
40
|
+
"\n" +
|
|
41
|
+
"Record an active review-monitor after spawning an Approach 1 poller (#2655).\n" +
|
|
42
|
+
"\n" +
|
|
43
|
+
"required:\n" +
|
|
44
|
+
" --pr N Pull request number\n" +
|
|
45
|
+
" --monitor-agent-id ID Stable poller agent id / Task handle\n" +
|
|
46
|
+
" --platform-primitive P start_agent | spawn_subagent | cursor-task\n" +
|
|
47
|
+
"\n" +
|
|
48
|
+
"options:\n" +
|
|
49
|
+
" --repo OWNER/REPO Repository\n" +
|
|
50
|
+
" --head-sha SHA HEAD SHA at monitor start\n" +
|
|
51
|
+
" --project-root PATH Project root (default: cwd)\n" +
|
|
52
|
+
" --parent-session-id ID Optional parent ritual / session id\n" +
|
|
53
|
+
"\n" +
|
|
54
|
+
"exit codes: 0 registered / 2 config error\n";
|
|
55
|
+
//# sourceMappingURL=constants.js.map
|