@bookedsolid/rea 0.10.3 → 0.11.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/.husky/pre-push +22 -167
- package/agents/codex-adversarial.md +5 -3
- package/commands/codex-review.md +3 -5
- package/dist/audit/append.d.ts +7 -32
- package/dist/audit/append.js +7 -35
- package/dist/cli/audit.d.ts +0 -31
- package/dist/cli/audit.js +5 -74
- package/dist/cli/doctor.js +6 -16
- package/dist/cli/hook.d.ts +48 -0
- package/dist/cli/hook.js +127 -0
- package/dist/cli/index.js +5 -80
- package/dist/cli/init.js +1 -1
- package/dist/cli/install/gitignore.d.ts +2 -2
- package/dist/cli/install/gitignore.js +3 -3
- package/dist/cli/install/pre-push.d.ts +146 -271
- package/dist/cli/install/pre-push.js +471 -2633
- package/dist/cli/install/settings-merge.d.ts +17 -0
- package/dist/cli/install/settings-merge.js +48 -1
- package/dist/cli/upgrade.js +131 -3
- package/dist/config/tier-map.js +18 -25
- package/dist/hooks/push-gate/base.d.ts +57 -0
- package/dist/hooks/push-gate/base.js +77 -0
- package/dist/hooks/push-gate/codex-runner.d.ts +126 -0
- package/dist/hooks/push-gate/codex-runner.js +223 -0
- package/dist/hooks/push-gate/findings.d.ts +68 -0
- package/dist/hooks/push-gate/findings.js +142 -0
- package/dist/hooks/push-gate/halt.d.ts +28 -0
- package/dist/hooks/push-gate/halt.js +49 -0
- package/dist/hooks/push-gate/index.d.ts +90 -0
- package/dist/hooks/push-gate/index.js +351 -0
- package/dist/hooks/push-gate/policy.d.ts +41 -0
- package/dist/hooks/push-gate/policy.js +55 -0
- package/dist/hooks/push-gate/report.d.ts +89 -0
- package/dist/hooks/push-gate/report.js +140 -0
- package/dist/policy/loader.d.ts +10 -10
- package/dist/policy/loader.js +7 -6
- package/dist/policy/types.d.ts +31 -22
- package/package.json +1 -1
- package/dist/cache/review-cache.d.ts +0 -115
- package/dist/cache/review-cache.js +0 -200
- package/dist/cli/cache.d.ts +0 -84
- package/dist/cli/cache.js +0 -150
- package/dist/hooks/review-gate/args.d.ts +0 -126
- package/dist/hooks/review-gate/args.js +0 -315
- package/dist/hooks/review-gate/audit.d.ts +0 -131
- package/dist/hooks/review-gate/audit.js +0 -181
- package/dist/hooks/review-gate/banner.d.ts +0 -97
- package/dist/hooks/review-gate/banner.js +0 -172
- package/dist/hooks/review-gate/base-resolve.d.ts +0 -155
- package/dist/hooks/review-gate/base-resolve.js +0 -247
- package/dist/hooks/review-gate/cache-key.d.ts +0 -55
- package/dist/hooks/review-gate/cache-key.js +0 -41
- package/dist/hooks/review-gate/cache.d.ts +0 -108
- package/dist/hooks/review-gate/cache.js +0 -120
- package/dist/hooks/review-gate/constants.d.ts +0 -26
- package/dist/hooks/review-gate/constants.js +0 -34
- package/dist/hooks/review-gate/diff.d.ts +0 -181
- package/dist/hooks/review-gate/diff.js +0 -232
- package/dist/hooks/review-gate/errors.d.ts +0 -72
- package/dist/hooks/review-gate/errors.js +0 -100
- package/dist/hooks/review-gate/hash.d.ts +0 -43
- package/dist/hooks/review-gate/hash.js +0 -46
- package/dist/hooks/review-gate/index.d.ts +0 -31
- package/dist/hooks/review-gate/index.js +0 -35
- package/dist/hooks/review-gate/metadata.d.ts +0 -98
- package/dist/hooks/review-gate/metadata.js +0 -158
- package/dist/hooks/review-gate/policy.d.ts +0 -55
- package/dist/hooks/review-gate/policy.js +0 -71
- package/dist/hooks/review-gate/protected-paths.d.ts +0 -46
- package/dist/hooks/review-gate/protected-paths.js +0 -76
- package/hooks/_lib/push-review-core.sh +0 -1250
- package/hooks/commit-review-gate.sh +0 -330
- package/hooks/push-review-gate-git.sh +0 -94
- package/hooks/push-review-gate.sh +0 -92
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Review-cache adapter for the push-review gate.
|
|
3
|
-
*
|
|
4
|
-
* ## What this module owns
|
|
5
|
-
*
|
|
6
|
-
* 1. Compute the cache key from a diff. **Re-exports** `computeCacheKey`
|
|
7
|
-
* from the Phase-1 `cache-key.ts` module — this is the same function,
|
|
8
|
-
* not a reimplementation. The fixture suite (`cache.test.ts`) locks
|
|
9
|
-
* that invariant via a byte-exact re-run against
|
|
10
|
-
* `__fixtures__/cache-keys.json`. If the two modules ever diverge,
|
|
11
|
-
* the 0.10.x → 0.11.0 cache contract is broken and every consumer's
|
|
12
|
-
* on-disk cache becomes unreachable. See design §8.
|
|
13
|
-
*
|
|
14
|
-
* 2. Wrap `src/cache/review-cache.ts` so callers get a single entry
|
|
15
|
-
* point — `checkReviewCache({ diff, branch, base })` — that hides
|
|
16
|
-
* the TTL semantics, the `(sha, branch, base)` key tuple, and the
|
|
17
|
-
* cache-lookup result shape.
|
|
18
|
-
*
|
|
19
|
-
* 3. Translate the cache lookup into the same three-way outcome the
|
|
20
|
-
* bash core's §1203 `jq -e '.hit == true and .result == "pass"'`
|
|
21
|
-
* check emitted:
|
|
22
|
-
*
|
|
23
|
-
* - `hit_pass` — cache hit AND result === 'pass'. Gate passes.
|
|
24
|
-
* - `hit_fail` — cache hit AND result === 'fail'. Cached
|
|
25
|
-
* negative verdict; gate blocks. (Bash §1197-1202
|
|
26
|
-
* rejects this; we preserve.)
|
|
27
|
-
* - `miss` — no hit / expired / empty file. Gate falls
|
|
28
|
-
* through to the review-required banner.
|
|
29
|
-
* - `query_error` — cache lookup threw. Bash §1180-1196 treated
|
|
30
|
-
* this as a `{"hit":false,"reason":"query_error"}`
|
|
31
|
-
* cached result; we carry the error body so the
|
|
32
|
-
* caller can emit the CACHE CHECK FAILED banner
|
|
33
|
-
* with the SANITIZED stderr (defect C0/C1 strip).
|
|
34
|
-
*
|
|
35
|
-
* ## Phase 2a scope
|
|
36
|
-
*
|
|
37
|
-
* This file exports pure functions over the already-TS
|
|
38
|
-
* `review-cache.ts`. No subprocess `spawn`, no CLI fork. The bash
|
|
39
|
-
* core's `rea cache check` subprocess hop is obviated entirely —
|
|
40
|
-
* once Phase 3 swaps the shim we no longer fork/exec node for the
|
|
41
|
-
* cache lookup at all.
|
|
42
|
-
*
|
|
43
|
-
* ## Phase 2b composition
|
|
44
|
-
*
|
|
45
|
-
* `runPushReviewGate` in `index.ts` calls `computeCacheKeyFromDiff` +
|
|
46
|
-
* `checkReviewCache` sequentially; the latter returns a discriminated
|
|
47
|
-
* outcome the gate branches on. No new behavior lands here — that's
|
|
48
|
-
* the `codex-gate.ts` / composition step.
|
|
49
|
-
*/
|
|
50
|
-
import { lookup } from '../../cache/review-cache.js';
|
|
51
|
-
import { computeCacheKey as computePhase1CacheKey } from './cache-key.js';
|
|
52
|
-
/**
|
|
53
|
-
* Compute the cache key for a diff. This is a thin re-export of Phase 1's
|
|
54
|
-
* `computeCacheKey` — exposed on this module so callers can use a single
|
|
55
|
-
* import when they need both the key AND the lookup.
|
|
56
|
-
*
|
|
57
|
-
* The function is UNCHANGED from Phase 1. The fixture suite in
|
|
58
|
-
* `cache.test.ts` proves byte-exact parity against
|
|
59
|
-
* `__fixtures__/cache-keys.json` for all six scenarios.
|
|
60
|
-
*/
|
|
61
|
-
export function computeCacheKey(diff) {
|
|
62
|
-
return computePhase1CacheKey({ diff });
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Perform a cache lookup and translate into the discriminated outcome.
|
|
66
|
-
*
|
|
67
|
-
* Does NOT throw on a lookup failure — every known error path routes
|
|
68
|
-
* through the `query_error` variant so the caller's single `switch`
|
|
69
|
-
* handles all four outcomes. This mirrors the bash core's
|
|
70
|
-
* `CACHE_STDOUT || CACHE_EXIT != 0 → {"hit":false,...}` collapse at
|
|
71
|
-
* §1180-1196.
|
|
72
|
-
*/
|
|
73
|
-
export async function checkReviewCache(input) {
|
|
74
|
-
const key = computeCacheKey(input.diff);
|
|
75
|
-
let result;
|
|
76
|
-
try {
|
|
77
|
-
result = await lookup(input.baseDir, {
|
|
78
|
-
sha: key,
|
|
79
|
-
branch: input.branch,
|
|
80
|
-
base: input.base,
|
|
81
|
-
...(input.nowMs !== undefined ? { nowMs: input.nowMs } : {}),
|
|
82
|
-
...(input.maxAgeSeconds !== undefined ? { maxAgeSeconds: input.maxAgeSeconds } : {}),
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
catch (err) {
|
|
86
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
87
|
-
return { kind: 'query_error', key, error: msg };
|
|
88
|
-
}
|
|
89
|
-
if (!result.hit) {
|
|
90
|
-
// `result.missReason` is always set when `hit` is false (see
|
|
91
|
-
// review-cache.ts's CacheLookupResult contract). The fallback to
|
|
92
|
-
// 'no-entry' is defensive for an ill-formed result we shouldn't see.
|
|
93
|
-
return {
|
|
94
|
-
kind: 'miss',
|
|
95
|
-
key,
|
|
96
|
-
reason: result.missReason ?? 'no-entry',
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
// Hit. Branch on verdict — the bash core requires BOTH hit==true AND
|
|
100
|
-
// result==pass. A hit with result==fail is a cached negative verdict
|
|
101
|
-
// and must NOT unblock the push.
|
|
102
|
-
const entry = result.entry;
|
|
103
|
-
if (entry === undefined) {
|
|
104
|
-
// Defensive: `hit: true` without an entry is an ill-formed result.
|
|
105
|
-
return { kind: 'miss', key, reason: 'no-entry' };
|
|
106
|
-
}
|
|
107
|
-
if (entry.result === 'pass') {
|
|
108
|
-
return { kind: 'hit_pass', key, recorded_at: entry.recorded_at };
|
|
109
|
-
}
|
|
110
|
-
// result === 'fail'
|
|
111
|
-
const hitFail = {
|
|
112
|
-
kind: 'hit_fail',
|
|
113
|
-
key,
|
|
114
|
-
recorded_at: entry.recorded_at,
|
|
115
|
-
};
|
|
116
|
-
if (entry.reason !== undefined && entry.reason.length > 0) {
|
|
117
|
-
hitFail.reason = entry.reason;
|
|
118
|
-
}
|
|
119
|
-
return hitFail;
|
|
120
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constants shared across the review-gate modules. Kept in one file so the
|
|
3
|
-
* values that a reader cares about (the all-zeros SHA, the empty-tree SHA,
|
|
4
|
-
* the protected-path set) are trivially grep-able.
|
|
5
|
-
*/
|
|
6
|
-
/** The git-native "null" SHA — a deletion on the pre-push contract. */
|
|
7
|
-
export declare const ZERO_SHA = "0000000000000000000000000000000000000000";
|
|
8
|
-
/**
|
|
9
|
-
* The canonical empty-tree SHA-1. Used as the merge-base baseline when a
|
|
10
|
-
* new-branch push has no remote-tracking ref to anchor on — `git diff
|
|
11
|
-
* <empty-tree>..<local_sha>` gives the full push content, and the gate
|
|
12
|
-
* treats it as a diff against nothing (which is what it is, operationally).
|
|
13
|
-
*/
|
|
14
|
-
export declare const EMPTY_TREE_SHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
15
|
-
/**
|
|
16
|
-
* The protected-path set. A push that touches any file under one of these
|
|
17
|
-
* prefixes requires a matching `codex.review` audit record with verdict in
|
|
18
|
-
* {pass, concerns} AND emission_source in {rea-cli, codex-cli}. See the
|
|
19
|
-
* THREAT_MODEL for the full threat statement, and the design doc §9 for
|
|
20
|
-
* the carry-forward from the bash core.
|
|
21
|
-
*
|
|
22
|
-
* Pattern format: leading/trailing slashes stripped; matched as directory
|
|
23
|
-
* prefixes by `protected-paths.ts`. Order is not significant (a hit on any
|
|
24
|
-
* entry is sufficient), but we keep the list sorted for grep-ability.
|
|
25
|
-
*/
|
|
26
|
-
export declare const PROTECTED_PATH_PREFIXES: readonly string[];
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constants shared across the review-gate modules. Kept in one file so the
|
|
3
|
-
* values that a reader cares about (the all-zeros SHA, the empty-tree SHA,
|
|
4
|
-
* the protected-path set) are trivially grep-able.
|
|
5
|
-
*/
|
|
6
|
-
/** The git-native "null" SHA — a deletion on the pre-push contract. */
|
|
7
|
-
export const ZERO_SHA = '0000000000000000000000000000000000000000';
|
|
8
|
-
/**
|
|
9
|
-
* The canonical empty-tree SHA-1. Used as the merge-base baseline when a
|
|
10
|
-
* new-branch push has no remote-tracking ref to anchor on — `git diff
|
|
11
|
-
* <empty-tree>..<local_sha>` gives the full push content, and the gate
|
|
12
|
-
* treats it as a diff against nothing (which is what it is, operationally).
|
|
13
|
-
*/
|
|
14
|
-
export const EMPTY_TREE_SHA = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
|
|
15
|
-
/**
|
|
16
|
-
* The protected-path set. A push that touches any file under one of these
|
|
17
|
-
* prefixes requires a matching `codex.review` audit record with verdict in
|
|
18
|
-
* {pass, concerns} AND emission_source in {rea-cli, codex-cli}. See the
|
|
19
|
-
* THREAT_MODEL for the full threat statement, and the design doc §9 for
|
|
20
|
-
* the carry-forward from the bash core.
|
|
21
|
-
*
|
|
22
|
-
* Pattern format: leading/trailing slashes stripped; matched as directory
|
|
23
|
-
* prefixes by `protected-paths.ts`. Order is not significant (a hit on any
|
|
24
|
-
* entry is sufficient), but we keep the list sorted for grep-ability.
|
|
25
|
-
*/
|
|
26
|
-
export const PROTECTED_PATH_PREFIXES = [
|
|
27
|
-
'.claude/hooks/',
|
|
28
|
-
'.github/workflows/',
|
|
29
|
-
'.husky/',
|
|
30
|
-
'.rea/',
|
|
31
|
-
'hooks/',
|
|
32
|
-
'src/gateway/middleware/',
|
|
33
|
-
'src/policy/',
|
|
34
|
-
];
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Git-subprocess wrappers the review gate needs.
|
|
3
|
-
*
|
|
4
|
-
* ## Why a dedicated module
|
|
5
|
-
*
|
|
6
|
-
* The bash core spawns git via inline `$(cd "$REA_ROOT" && git ... 2>/dev/null)`
|
|
7
|
-
* subshells. Each invocation carries a handful of concerns the TS port
|
|
8
|
-
* separates cleanly:
|
|
9
|
-
*
|
|
10
|
-
* - Args passed as an ARRAY so the shell never interprets them
|
|
11
|
-
* (push-review-ts-port design §9 security posture: no argument-injection
|
|
12
|
-
* CVEs around refspec names like `main;rm -rf /`).
|
|
13
|
-
* - `cwd` always set to the resolved repo root — the caller never has to
|
|
14
|
-
* remember to `cd` first.
|
|
15
|
-
* - stdout/stderr captured separately. Git's error text goes to stderr in
|
|
16
|
-
* normal modes, and callers often want stderr for diagnostics while
|
|
17
|
-
* still deciding based on exit code.
|
|
18
|
-
* - A single shared timeout (10s) catches a hung `git` process. The bash
|
|
19
|
-
* core had no timeout — an upstream `git` stuck on NFS could wedge the
|
|
20
|
-
* whole push indefinitely.
|
|
21
|
-
*
|
|
22
|
-
* ## Mockability
|
|
23
|
-
*
|
|
24
|
-
* Every exported function takes a `GitRunner` as its first positional so
|
|
25
|
-
* tests can stub the subprocess layer. The default runner spawns `git`;
|
|
26
|
-
* tests supply a recording runner and assert over the command history. This
|
|
27
|
-
* is how `base-resolve.test.ts` and `diff.test.ts` avoid needing a real
|
|
28
|
-
* git repo.
|
|
29
|
-
*
|
|
30
|
-
* ## Defect carry-forwards
|
|
31
|
-
*
|
|
32
|
-
* - Two-dot `A..B` for diff inputs, NEVER three-dot `A...B`. The bash
|
|
33
|
-
* core's comment on push-review-core.sh §1053-1060 covers this: three-dot
|
|
34
|
-
* computes an implicit merge-base which FAILS when A is the empty-tree
|
|
35
|
-
* SHA (a valid bootstrap anchor in `base-resolve.ts`). Two-dot accepts
|
|
36
|
-
* any revision on the left.
|
|
37
|
-
* - `git diff --name-status` output is tab-separated, one line per change;
|
|
38
|
-
* `protected-paths.ts` owns the parse.
|
|
39
|
-
* - `git cat-file -e <sha>^{commit}` is the "object is locally resolvable"
|
|
40
|
-
* probe. Bash used a bare exit-code check; we preserve that.
|
|
41
|
-
*/
|
|
42
|
-
/**
|
|
43
|
-
* Result of a git invocation. `status` is the git exit code (0 on success).
|
|
44
|
-
* Both `stdout` and `stderr` are trimmed of trailing newlines — the bash
|
|
45
|
-
* core's callers all applied `$(...)` which already collapses trailing
|
|
46
|
-
* whitespace, so TS callers expect the same contract.
|
|
47
|
-
*/
|
|
48
|
-
export interface GitRunResult {
|
|
49
|
-
status: number;
|
|
50
|
-
stdout: string;
|
|
51
|
-
stderr: string;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Signature the git-subprocess layer must implement. Tests supply a stub
|
|
55
|
-
* that records calls and returns canned results; production uses
|
|
56
|
-
* {@link spawnGit}.
|
|
57
|
-
*/
|
|
58
|
-
export type GitRunner = (args: readonly string[], cwd: string) => GitRunResult;
|
|
59
|
-
/**
|
|
60
|
-
* Default production git runner. Spawns `git` with the supplied args, cwd,
|
|
61
|
-
* and a fixed timeout. `encoding: 'utf8'` so the returned strings are
|
|
62
|
-
* decoded, matching the bash `$()` shape.
|
|
63
|
-
*
|
|
64
|
-
* Security: args is always an array; no shell string ever participates in
|
|
65
|
-
* the invocation. Refspec names that happen to contain shell metacharacters
|
|
66
|
-
* are inert.
|
|
67
|
-
*/
|
|
68
|
-
export declare function spawnGit(args: readonly string[], cwd: string): GitRunResult;
|
|
69
|
-
/**
|
|
70
|
-
* Return the current branch name (empty string when detached or on failure).
|
|
71
|
-
* Bash-core parity (push-review-core.sh §687): `git branch --show-current`.
|
|
72
|
-
*/
|
|
73
|
-
export declare function currentBranch(runner: GitRunner, cwd: string): string;
|
|
74
|
-
/**
|
|
75
|
-
* Resolve `HEAD` to a commit SHA, or return the empty string when the repo
|
|
76
|
-
* has no commits / the rev-parse fails. Bash-core parity
|
|
77
|
-
* (push-review-core.sh §134 and §412): `git rev-parse HEAD`.
|
|
78
|
-
*/
|
|
79
|
-
export declare function resolveHead(runner: GitRunner, cwd: string): string;
|
|
80
|
-
/**
|
|
81
|
-
* Resolve a ref (e.g. `feature/foo`) to a commit SHA via
|
|
82
|
-
* `git rev-parse --verify <ref>^{commit}`, or return null on failure.
|
|
83
|
-
* Bash-core parity (push-review-core.sh §187): the `^{commit}` suffix
|
|
84
|
-
* forces resolution to the commit even for annotated-tag refs.
|
|
85
|
-
*/
|
|
86
|
-
export declare function resolveRefToSha(runner: GitRunner, cwd: string, ref: string): string | null;
|
|
87
|
-
/**
|
|
88
|
-
* Return the short-name upstream for the current branch (e.g. `origin/main`)
|
|
89
|
-
* or null if no upstream is set. Bash-core parity (push-review-core.sh §129
|
|
90
|
-
* and §601): `git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}'`.
|
|
91
|
-
*/
|
|
92
|
-
export declare function resolveUpstream(runner: GitRunner, cwd: string): string | null;
|
|
93
|
-
/**
|
|
94
|
-
* Check whether a commit object is locally resolvable. Bash-core parity
|
|
95
|
-
* (push-review-core.sh §743): `git cat-file -e <sha>^{commit}`. Returns
|
|
96
|
-
* true on exit 0, false otherwise. Used before merge-base computation on
|
|
97
|
-
* the non-new-branch path — if the remote ref isn't fetched, `git merge-
|
|
98
|
-
* base` would silently return an unrelated base and the gate would diff
|
|
99
|
-
* against the wrong anchor.
|
|
100
|
-
*/
|
|
101
|
-
export declare function hasCommitLocally(runner: GitRunner, cwd: string, sha: string): boolean;
|
|
102
|
-
/**
|
|
103
|
-
* Compute the merge-base between two refs. Returns the SHA on success,
|
|
104
|
-
* null on failure or empty output. Bash-core parity
|
|
105
|
-
* (push-review-core.sh §756 and §860): `git merge-base <a> <b>`.
|
|
106
|
-
*/
|
|
107
|
-
export declare function mergeBase(runner: GitRunner, cwd: string, a: string, b: string): string | null;
|
|
108
|
-
/**
|
|
109
|
-
* True iff `ref` is a resolvable rev (commit, tag, or branch). Bash-core
|
|
110
|
-
* parity (push-review-core.sh §815 and §835): `git rev-parse --verify
|
|
111
|
-
* --quiet <ref>` with stdout suppressed and stderr ignored.
|
|
112
|
-
*/
|
|
113
|
-
export declare function refExists(runner: GitRunner, cwd: string, ref: string): boolean;
|
|
114
|
-
/**
|
|
115
|
-
* Read a git config value (e.g. `branch.<name>.base`). Returns the value
|
|
116
|
-
* or the empty string when the config entry is absent or `git config` fails.
|
|
117
|
-
* Bash-core parity (push-review-core.sh §808): `git config --get <key>`.
|
|
118
|
-
*/
|
|
119
|
-
export declare function readGitConfig(runner: GitRunner, cwd: string, key: string): string;
|
|
120
|
-
/**
|
|
121
|
-
* Resolve `refs/remotes/<remote>/HEAD` to its symbolic target (e.g.
|
|
122
|
-
* `refs/remotes/origin/main`). Returns null on failure. Bash-core parity
|
|
123
|
-
* (push-review-core.sh §826): `git symbolic-ref refs/remotes/<remote>/HEAD`.
|
|
124
|
-
*/
|
|
125
|
-
export declare function resolveRemoteDefaultRef(runner: GitRunner, cwd: string, remote: string): string | null;
|
|
126
|
-
/**
|
|
127
|
-
* Full `git diff <a>..<b>` output (two-dot per the §1053-1060 rationale).
|
|
128
|
-
* Returns the diff body on success; throws via the typed error if git
|
|
129
|
-
* exits non-zero so the caller can translate to the banner + exit 2.
|
|
130
|
-
*
|
|
131
|
-
* Empty diff → empty string, status 0 is a legitimate no-op push and the
|
|
132
|
-
* caller routes to its "no reviewable diff" branch.
|
|
133
|
-
*/
|
|
134
|
-
export interface DiffResult {
|
|
135
|
-
/** The full `git diff` output (may be empty). */
|
|
136
|
-
diff: string;
|
|
137
|
-
/** git's exit code. */
|
|
138
|
-
status: number;
|
|
139
|
-
/** git's stderr for error-path diagnostics. */
|
|
140
|
-
stderr: string;
|
|
141
|
-
}
|
|
142
|
-
export declare function fullDiff(runner: GitRunner, cwd: string, a: string, b: string): DiffResult;
|
|
143
|
-
/**
|
|
144
|
-
* `git diff --name-status <a>..<b>` output. One line per change, tab-
|
|
145
|
-
* separated `<STATUS>\t<path1>[\t<path2>]`. Consumed by
|
|
146
|
-
* `protected-paths.ts`. Returns stdout on success or null on error (the
|
|
147
|
-
* caller emits a banner + exit 2; see bash core §904-914).
|
|
148
|
-
*/
|
|
149
|
-
export interface NameStatusResult {
|
|
150
|
-
/** Raw name-status output (may be empty on a zero-change diff). */
|
|
151
|
-
output: string;
|
|
152
|
-
/** git's exit code. */
|
|
153
|
-
status: number;
|
|
154
|
-
/** git's stderr for error-path diagnostics. */
|
|
155
|
-
stderr: string;
|
|
156
|
-
}
|
|
157
|
-
export declare function diffNameStatus(runner: GitRunner, cwd: string, a: string, b: string): NameStatusResult;
|
|
158
|
-
/**
|
|
159
|
-
* Commit count between two refs. Bash-core parity
|
|
160
|
-
* (push-review-core.sh §996): `git rev-list --count <a>..<b>`. Returns -1
|
|
161
|
-
* on error so callers can distinguish "git failed" (exit 2) from "zero
|
|
162
|
-
* commits" (legitimate, usually a same-ref push).
|
|
163
|
-
*/
|
|
164
|
-
export declare function revListCount(runner: GitRunner, cwd: string, a: string, b: string): number;
|
|
165
|
-
/**
|
|
166
|
-
* Resolve the repository's common-dir (the path to `.git` or to a
|
|
167
|
-
* shared worktree parent). Returns the absolute path or null when not in
|
|
168
|
-
* a git repo. Bash-core parity (push-review-core.sh §272-273):
|
|
169
|
-
* `git rev-parse --path-format=absolute --git-common-dir`.
|
|
170
|
-
*
|
|
171
|
-
* Used by the cross-repo guard in §1a to distinguish two checkouts of the
|
|
172
|
-
* same repo (linked worktrees share a common-dir) from two unrelated
|
|
173
|
-
* repos. Phase 2a ships the primitive; composition happens in Phase 2b.
|
|
174
|
-
*/
|
|
175
|
-
export declare function gitCommonDir(runner: GitRunner, cwd: string): string | null;
|
|
176
|
-
/**
|
|
177
|
-
* Read git's user email + name fallback for skip-audit actor attribution.
|
|
178
|
-
* Bash-core parity (push-review-core.sh §393-396 and §563-566): prefer
|
|
179
|
-
* email; fall back to name if email is empty; empty string if both missing.
|
|
180
|
-
*/
|
|
181
|
-
export declare function readGitActor(runner: GitRunner, cwd: string): string;
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Git-subprocess wrappers the review gate needs.
|
|
3
|
-
*
|
|
4
|
-
* ## Why a dedicated module
|
|
5
|
-
*
|
|
6
|
-
* The bash core spawns git via inline `$(cd "$REA_ROOT" && git ... 2>/dev/null)`
|
|
7
|
-
* subshells. Each invocation carries a handful of concerns the TS port
|
|
8
|
-
* separates cleanly:
|
|
9
|
-
*
|
|
10
|
-
* - Args passed as an ARRAY so the shell never interprets them
|
|
11
|
-
* (push-review-ts-port design §9 security posture: no argument-injection
|
|
12
|
-
* CVEs around refspec names like `main;rm -rf /`).
|
|
13
|
-
* - `cwd` always set to the resolved repo root — the caller never has to
|
|
14
|
-
* remember to `cd` first.
|
|
15
|
-
* - stdout/stderr captured separately. Git's error text goes to stderr in
|
|
16
|
-
* normal modes, and callers often want stderr for diagnostics while
|
|
17
|
-
* still deciding based on exit code.
|
|
18
|
-
* - A single shared timeout (10s) catches a hung `git` process. The bash
|
|
19
|
-
* core had no timeout — an upstream `git` stuck on NFS could wedge the
|
|
20
|
-
* whole push indefinitely.
|
|
21
|
-
*
|
|
22
|
-
* ## Mockability
|
|
23
|
-
*
|
|
24
|
-
* Every exported function takes a `GitRunner` as its first positional so
|
|
25
|
-
* tests can stub the subprocess layer. The default runner spawns `git`;
|
|
26
|
-
* tests supply a recording runner and assert over the command history. This
|
|
27
|
-
* is how `base-resolve.test.ts` and `diff.test.ts` avoid needing a real
|
|
28
|
-
* git repo.
|
|
29
|
-
*
|
|
30
|
-
* ## Defect carry-forwards
|
|
31
|
-
*
|
|
32
|
-
* - Two-dot `A..B` for diff inputs, NEVER three-dot `A...B`. The bash
|
|
33
|
-
* core's comment on push-review-core.sh §1053-1060 covers this: three-dot
|
|
34
|
-
* computes an implicit merge-base which FAILS when A is the empty-tree
|
|
35
|
-
* SHA (a valid bootstrap anchor in `base-resolve.ts`). Two-dot accepts
|
|
36
|
-
* any revision on the left.
|
|
37
|
-
* - `git diff --name-status` output is tab-separated, one line per change;
|
|
38
|
-
* `protected-paths.ts` owns the parse.
|
|
39
|
-
* - `git cat-file -e <sha>^{commit}` is the "object is locally resolvable"
|
|
40
|
-
* probe. Bash used a bare exit-code check; we preserve that.
|
|
41
|
-
*/
|
|
42
|
-
import { spawnSync } from 'node:child_process';
|
|
43
|
-
/** Hard cap on git invocation runtime. Bash core had no cap; 10s is generous for a hot-cache repo. */
|
|
44
|
-
const GIT_TIMEOUT_MS = 10_000;
|
|
45
|
-
/**
|
|
46
|
-
* Default production git runner. Spawns `git` with the supplied args, cwd,
|
|
47
|
-
* and a fixed timeout. `encoding: 'utf8'` so the returned strings are
|
|
48
|
-
* decoded, matching the bash `$()` shape.
|
|
49
|
-
*
|
|
50
|
-
* Security: args is always an array; no shell string ever participates in
|
|
51
|
-
* the invocation. Refspec names that happen to contain shell metacharacters
|
|
52
|
-
* are inert.
|
|
53
|
-
*/
|
|
54
|
-
export function spawnGit(args, cwd) {
|
|
55
|
-
const opts = {
|
|
56
|
-
cwd,
|
|
57
|
-
encoding: 'utf8',
|
|
58
|
-
timeout: GIT_TIMEOUT_MS,
|
|
59
|
-
// Explicitly drop stdin — some git subcommands try to read (e.g. `git
|
|
60
|
-
// commit` prompting for a message); we never want that.
|
|
61
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
62
|
-
// Never use a shell. Args are an array; spawn does argv[0] execve
|
|
63
|
-
// directly, so `git` is looked up on PATH with no shell parsing.
|
|
64
|
-
shell: false,
|
|
65
|
-
};
|
|
66
|
-
const result = spawnSync('git', args, opts);
|
|
67
|
-
const stdout = typeof result.stdout === 'string' ? result.stdout.replace(/\n+$/, '') : '';
|
|
68
|
-
const stderr = typeof result.stderr === 'string' ? result.stderr.replace(/\n+$/, '') : '';
|
|
69
|
-
// On timeout/signal kill, spawnSync returns status=null and populates
|
|
70
|
-
// `signal`. Treat as a non-zero exit so callers fall through the normal
|
|
71
|
-
// error paths.
|
|
72
|
-
const status = typeof result.status === 'number' ? result.status : 1;
|
|
73
|
-
return { status, stdout, stderr };
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* SHA validator. Bash uses `=~ ^[0-9a-f]{40}$`; we match exactly.
|
|
77
|
-
*/
|
|
78
|
-
const SHA_HEX_40 = /^[0-9a-f]{40}$/;
|
|
79
|
-
/**
|
|
80
|
-
* Return the current branch name (empty string when detached or on failure).
|
|
81
|
-
* Bash-core parity (push-review-core.sh §687): `git branch --show-current`.
|
|
82
|
-
*/
|
|
83
|
-
export function currentBranch(runner, cwd) {
|
|
84
|
-
const r = runner(['branch', '--show-current'], cwd);
|
|
85
|
-
if (r.status !== 0)
|
|
86
|
-
return '';
|
|
87
|
-
return r.stdout;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Resolve `HEAD` to a commit SHA, or return the empty string when the repo
|
|
91
|
-
* has no commits / the rev-parse fails. Bash-core parity
|
|
92
|
-
* (push-review-core.sh §134 and §412): `git rev-parse HEAD`.
|
|
93
|
-
*/
|
|
94
|
-
export function resolveHead(runner, cwd) {
|
|
95
|
-
const r = runner(['rev-parse', 'HEAD'], cwd);
|
|
96
|
-
if (r.status !== 0)
|
|
97
|
-
return '';
|
|
98
|
-
const sha = r.stdout;
|
|
99
|
-
return SHA_HEX_40.test(sha) ? sha : '';
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Resolve a ref (e.g. `feature/foo`) to a commit SHA via
|
|
103
|
-
* `git rev-parse --verify <ref>^{commit}`, or return null on failure.
|
|
104
|
-
* Bash-core parity (push-review-core.sh §187): the `^{commit}` suffix
|
|
105
|
-
* forces resolution to the commit even for annotated-tag refs.
|
|
106
|
-
*/
|
|
107
|
-
export function resolveRefToSha(runner, cwd, ref) {
|
|
108
|
-
const r = runner(['rev-parse', '--verify', `${ref}^{commit}`], cwd);
|
|
109
|
-
if (r.status !== 0)
|
|
110
|
-
return null;
|
|
111
|
-
const sha = r.stdout;
|
|
112
|
-
return SHA_HEX_40.test(sha) ? sha : null;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Return the short-name upstream for the current branch (e.g. `origin/main`)
|
|
116
|
-
* or null if no upstream is set. Bash-core parity (push-review-core.sh §129
|
|
117
|
-
* and §601): `git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}'`.
|
|
118
|
-
*/
|
|
119
|
-
export function resolveUpstream(runner, cwd) {
|
|
120
|
-
const r = runner(['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'], cwd);
|
|
121
|
-
if (r.status !== 0)
|
|
122
|
-
return null;
|
|
123
|
-
const out = r.stdout;
|
|
124
|
-
return out.length > 0 ? out : null;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Check whether a commit object is locally resolvable. Bash-core parity
|
|
128
|
-
* (push-review-core.sh §743): `git cat-file -e <sha>^{commit}`. Returns
|
|
129
|
-
* true on exit 0, false otherwise. Used before merge-base computation on
|
|
130
|
-
* the non-new-branch path — if the remote ref isn't fetched, `git merge-
|
|
131
|
-
* base` would silently return an unrelated base and the gate would diff
|
|
132
|
-
* against the wrong anchor.
|
|
133
|
-
*/
|
|
134
|
-
export function hasCommitLocally(runner, cwd, sha) {
|
|
135
|
-
if (!SHA_HEX_40.test(sha))
|
|
136
|
-
return false;
|
|
137
|
-
const r = runner(['cat-file', '-e', `${sha}^{commit}`], cwd);
|
|
138
|
-
return r.status === 0;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Compute the merge-base between two refs. Returns the SHA on success,
|
|
142
|
-
* null on failure or empty output. Bash-core parity
|
|
143
|
-
* (push-review-core.sh §756 and §860): `git merge-base <a> <b>`.
|
|
144
|
-
*/
|
|
145
|
-
export function mergeBase(runner, cwd, a, b) {
|
|
146
|
-
const r = runner(['merge-base', a, b], cwd);
|
|
147
|
-
if (r.status !== 0)
|
|
148
|
-
return null;
|
|
149
|
-
const sha = r.stdout;
|
|
150
|
-
return SHA_HEX_40.test(sha) ? sha : null;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* True iff `ref` is a resolvable rev (commit, tag, or branch). Bash-core
|
|
154
|
-
* parity (push-review-core.sh §815 and §835): `git rev-parse --verify
|
|
155
|
-
* --quiet <ref>` with stdout suppressed and stderr ignored.
|
|
156
|
-
*/
|
|
157
|
-
export function refExists(runner, cwd, ref) {
|
|
158
|
-
const r = runner(['rev-parse', '--verify', '--quiet', ref], cwd);
|
|
159
|
-
return r.status === 0;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Read a git config value (e.g. `branch.<name>.base`). Returns the value
|
|
163
|
-
* or the empty string when the config entry is absent or `git config` fails.
|
|
164
|
-
* Bash-core parity (push-review-core.sh §808): `git config --get <key>`.
|
|
165
|
-
*/
|
|
166
|
-
export function readGitConfig(runner, cwd, key) {
|
|
167
|
-
const r = runner(['config', '--get', key], cwd);
|
|
168
|
-
if (r.status !== 0)
|
|
169
|
-
return '';
|
|
170
|
-
return r.stdout;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Resolve `refs/remotes/<remote>/HEAD` to its symbolic target (e.g.
|
|
174
|
-
* `refs/remotes/origin/main`). Returns null on failure. Bash-core parity
|
|
175
|
-
* (push-review-core.sh §826): `git symbolic-ref refs/remotes/<remote>/HEAD`.
|
|
176
|
-
*/
|
|
177
|
-
export function resolveRemoteDefaultRef(runner, cwd, remote) {
|
|
178
|
-
const r = runner(['symbolic-ref', `refs/remotes/${remote}/HEAD`], cwd);
|
|
179
|
-
if (r.status !== 0)
|
|
180
|
-
return null;
|
|
181
|
-
const out = r.stdout;
|
|
182
|
-
return out.length > 0 ? out : null;
|
|
183
|
-
}
|
|
184
|
-
export function fullDiff(runner, cwd, a, b) {
|
|
185
|
-
const r = runner(['diff', `${a}..${b}`], cwd);
|
|
186
|
-
return { diff: r.stdout, status: r.status, stderr: r.stderr };
|
|
187
|
-
}
|
|
188
|
-
export function diffNameStatus(runner, cwd, a, b) {
|
|
189
|
-
const r = runner(['diff', '--name-status', `${a}..${b}`], cwd);
|
|
190
|
-
return { output: r.stdout, status: r.status, stderr: r.stderr };
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Commit count between two refs. Bash-core parity
|
|
194
|
-
* (push-review-core.sh §996): `git rev-list --count <a>..<b>`. Returns -1
|
|
195
|
-
* on error so callers can distinguish "git failed" (exit 2) from "zero
|
|
196
|
-
* commits" (legitimate, usually a same-ref push).
|
|
197
|
-
*/
|
|
198
|
-
export function revListCount(runner, cwd, a, b) {
|
|
199
|
-
const r = runner(['rev-list', '--count', `${a}..${b}`], cwd);
|
|
200
|
-
if (r.status !== 0)
|
|
201
|
-
return -1;
|
|
202
|
-
const n = Number.parseInt(r.stdout, 10);
|
|
203
|
-
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Resolve the repository's common-dir (the path to `.git` or to a
|
|
207
|
-
* shared worktree parent). Returns the absolute path or null when not in
|
|
208
|
-
* a git repo. Bash-core parity (push-review-core.sh §272-273):
|
|
209
|
-
* `git rev-parse --path-format=absolute --git-common-dir`.
|
|
210
|
-
*
|
|
211
|
-
* Used by the cross-repo guard in §1a to distinguish two checkouts of the
|
|
212
|
-
* same repo (linked worktrees share a common-dir) from two unrelated
|
|
213
|
-
* repos. Phase 2a ships the primitive; composition happens in Phase 2b.
|
|
214
|
-
*/
|
|
215
|
-
export function gitCommonDir(runner, cwd) {
|
|
216
|
-
const r = runner(['rev-parse', '--path-format=absolute', '--git-common-dir'], cwd);
|
|
217
|
-
if (r.status !== 0)
|
|
218
|
-
return null;
|
|
219
|
-
const out = r.stdout;
|
|
220
|
-
return out.length > 0 ? out : null;
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Read git's user email + name fallback for skip-audit actor attribution.
|
|
224
|
-
* Bash-core parity (push-review-core.sh §393-396 and §563-566): prefer
|
|
225
|
-
* email; fall back to name if email is empty; empty string if both missing.
|
|
226
|
-
*/
|
|
227
|
-
export function readGitActor(runner, cwd) {
|
|
228
|
-
const email = readGitConfig(runner, cwd, 'user.email');
|
|
229
|
-
if (email.length > 0)
|
|
230
|
-
return email;
|
|
231
|
-
return readGitConfig(runner, cwd, 'user.name');
|
|
232
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Typed error set for the review-gate modules (G — push-review/commit-review
|
|
3
|
-
* TypeScript port).
|
|
4
|
-
*
|
|
5
|
-
* The bash core signals outcomes via exit codes + stderr banners. The TS port
|
|
6
|
-
* expresses each outcome as a typed error so callers can branch on class
|
|
7
|
-
* instead of parsing banner text, and so the eventual CLI entry point can
|
|
8
|
-
* translate a thrown error into the same exit code + banner the bash core
|
|
9
|
-
* emitted (preserving external contract per design §2, non-goals).
|
|
10
|
-
*
|
|
11
|
-
* Every error subclass carries:
|
|
12
|
-
* - a stable `code` (for programmatic dispatch in tests + the CLI shim)
|
|
13
|
-
* - an `exitCode` (matches the bash core's `exit N` semantics)
|
|
14
|
-
* - the operator-facing `message` composed by `banner.ts`
|
|
15
|
-
*
|
|
16
|
-
* This module is intentionally dependency-free so unit tests can import it
|
|
17
|
-
* without dragging in fs/child_process. The CLI entry point is the single
|
|
18
|
-
* place that translates these to `process.exit(N)`.
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
|
-
* Stable discriminator used by tests and the CLI dispatch layer. String literals
|
|
22
|
-
* (not enum) so they survive JSON serialization in audit metadata.
|
|
23
|
-
*/
|
|
24
|
-
export type ReviewGateErrorCode = 'PUSH_BLOCKED_DELETE' | 'PUSH_BLOCKED_HEAD_REFSPEC' | 'PUSH_BLOCKED_SOURCE_UNRESOLVABLE' | 'PUSH_BLOCKED_NO_REFSPECS' | 'PUSH_BLOCKED_REMOTE_OBJECT_MISSING' | 'PUSH_BLOCKED_NO_MERGE_BASE' | 'PUSH_BLOCKED_NO_BASE_RESOLVABLE' | 'PUSH_BLOCKED_DIFF_FAILED' | 'PUSH_BLOCKED_REV_LIST_FAILED' | 'PUSH_BLOCKED_PROTECTED_PATHS' | 'PUSH_BLOCKED_SKIP_REFUSED_IN_CI' | 'PUSH_BLOCKED_SKIP_NO_ACTOR' | 'PUSH_BLOCKED_SKIP_AUDIT_FAILED' | 'PUSH_BLOCKED_SKIP_NOT_BUILT' | 'PUSH_BLOCKED_SKIP_METADATA_FAILED' | 'PUSH_BLOCKED_CACHE_MKTEMP_UNAVAILABLE' | 'PUSH_BLOCKED_NOT_IN_REPO' | 'PUSH_BLOCKED_DEPENDENCY_MISSING' | 'PUSH_REVIEW_REQUIRED';
|
|
25
|
-
/**
|
|
26
|
-
* Base class. All review-gate errors derive from this so a CLI dispatch layer
|
|
27
|
-
* can `catch (e) { if (e instanceof ReviewGateError) ... }`.
|
|
28
|
-
*/
|
|
29
|
-
export declare class ReviewGateError extends Error {
|
|
30
|
-
readonly code: ReviewGateErrorCode;
|
|
31
|
-
readonly exitCode: number;
|
|
32
|
-
readonly details: Record<string, unknown>;
|
|
33
|
-
constructor(code: ReviewGateErrorCode, message: string, exitCode: number, details?: Record<string, unknown>);
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Blocked-push errors (exit 2). The bash core uses exit 2 for every blocked
|
|
37
|
-
* condition; we preserve that invariant so the shim's exit code is unchanged.
|
|
38
|
-
*/
|
|
39
|
-
export declare class BlockedError extends ReviewGateError {
|
|
40
|
-
constructor(code: ReviewGateErrorCode, message: string, details?: Record<string, unknown>);
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Deletion detected anywhere in the push (defect J). Must fail-closed even
|
|
44
|
-
* when a sibling refspec would have been reviewable.
|
|
45
|
-
*/
|
|
46
|
-
export declare class DeletionBlockedError extends BlockedError {
|
|
47
|
-
constructor();
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* A refspec with `HEAD` as destination is operator error (design §3.1,
|
|
51
|
-
* `pr_resolve_argv_refspecs`). Carry the refspec in details for banner render.
|
|
52
|
-
*/
|
|
53
|
-
export declare class HeadRefspecBlockedError extends BlockedError {
|
|
54
|
-
constructor(spec: string);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Invalid `--delete` refspec (empty destination or HEAD destination).
|
|
58
|
-
* Distinct from the general HEAD-refspec error because bash emits a
|
|
59
|
-
* different operator banner for the delete-mode case — the remediation
|
|
60
|
-
* text is "name the branch you meant to delete" rather than the HEAD
|
|
61
|
-
* destination error. See push-review-core.sh §161-168.
|
|
62
|
-
*/
|
|
63
|
-
export declare class InvalidDeleteRefspecError extends BlockedError {
|
|
64
|
-
constructor(spec: string);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Defect N completion (landed in phase 4, type reserved in phase 1 so
|
|
68
|
-
* `base-resolve.ts` can throw it later without schema churn).
|
|
69
|
-
*/
|
|
70
|
-
export declare class NoBaseResolvableError extends BlockedError {
|
|
71
|
-
constructor(source: string);
|
|
72
|
-
}
|