bareloop 0.8.0 → 0.9.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/CHANGELOG.md +421 -0
- package/README.md +10 -3
- package/bareloop.context.md +198 -17
- package/package.json +1 -1
- package/src/authorflow.js +1280 -0
- package/src/authoring.js +1296 -0
- package/src/authorjob.js +793 -0
- package/src/authorscout.js +706 -0
- package/src/bridges.js +2 -2
- package/src/declaredclose.js +519 -0
- package/src/index.js +72 -0
- package/src/job.js +48 -4
- package/src/kinds.js +1354 -0
- package/src/ledger.js +13 -0
- package/src/plan.js +26 -1
- package/src/planrun.js +239 -16
- package/src/ralph.js +19 -4
- package/src/reuse.js +68 -7
- package/src/root.js +8 -1
- package/src/run.js +10 -3
- package/src/text.js +120 -0
- package/src/workbranch.js +261 -0
- package/types/authorflow.d.ts +720 -0
- package/types/authoring.d.ts +447 -0
- package/types/authorjob.d.ts +241 -0
- package/types/authorscout.d.ts +307 -0
- package/types/declaredclose.d.ts +174 -0
- package/types/index.d.ts +9 -1
- package/types/job.d.ts +1 -0
- package/types/kinds.d.ts +343 -0
- package/types/plan.d.ts +18 -0
- package/types/planrun.d.ts +10 -3
- package/types/ralph.d.ts +1 -0
- package/types/run.d.ts +10 -2
- package/types/text.d.ts +84 -0
- package/types/workbranch.d.ts +102 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/** @param {any} job @returns {boolean} */
|
|
2
|
+
export function isDeclaredClose(job: any): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* The declaration's stages as the RUNNER's stage descriptors: the declared
|
|
5
|
+
* `{name, kind, params}` plus the arbiter's own `gapKeep`.
|
|
6
|
+
*
|
|
7
|
+
* `offer` and `needs` pass through untouched when a declaration carries them
|
|
8
|
+
* (v1's schema does not let one), so `checkMenu`'s derivation is unchanged.
|
|
9
|
+
* @param {any} closeDecl
|
|
10
|
+
* @returns {any[]|null} null when this is not a declaration
|
|
11
|
+
*/
|
|
12
|
+
export function declaredStages(closeDecl: any): any[] | null;
|
|
13
|
+
/**
|
|
14
|
+
* Validate a `closeDecl` as a JOB SPEC field: the envelope (genre, language,
|
|
15
|
+
* notes) plus M2's full declaration validator underneath it.
|
|
16
|
+
*
|
|
17
|
+
* `listing` is what splits the two callers, and the split is deliberate:
|
|
18
|
+
* - the JOB VALIDATOR has no repository, so it passes nothing and gets
|
|
19
|
+
* `grounded: false` — every tree-independent rule runs, the path rule and
|
|
20
|
+
* the scoped-job derivation do not;
|
|
21
|
+
* - the RUNNER has the real seed, so it passes the real listing and gets
|
|
22
|
+
* `grounded: true`. It runs this BEFORE any stage and before any token, so
|
|
23
|
+
* the deferred half is proved rather than skipped.
|
|
24
|
+
* A caller that passes neither a listing nor `deferListing` gets M2's
|
|
25
|
+
* `listing-absent` red, unchanged: a validator handed nothing to check against
|
|
26
|
+
* must refuse, never report a declaration it never examined.
|
|
27
|
+
*
|
|
28
|
+
* THREE checks now ride on the listing, not two: the path rule, the scoped-job
|
|
29
|
+
* derivation, and the GROUNDING of a recorded `genreEnv` (a by-value comparison
|
|
30
|
+
* between two copies inside one hand-editable spec proves they agree, never that
|
|
31
|
+
* the arbiter wrote them — see `ungroundedGenreEnv`). All three are deferred at
|
|
32
|
+
* the job-spec gate and all three are re-run GROUNDED by the runner before any
|
|
33
|
+
* stage executes, so the deferral moves the check rather than dropping it. The
|
|
34
|
+
* grounded gates are `prepareSigning`'s gate 1b — where the signature is minted,
|
|
35
|
+
* so a forged env can never be signed in the first place — and `runPlan`'s
|
|
36
|
+
* pre-flight, which catches a spec edited after signing.
|
|
37
|
+
*
|
|
38
|
+
* `verdictType` is the class the USER picked, and it is REQUIRED here because
|
|
39
|
+
* the guard battery keys off it (PRD v1.57 §2): with no class in hand there is
|
|
40
|
+
* no battery, and M2 would be handed nothing to check D5 against. It arrives
|
|
41
|
+
* from the spec's sibling `verdictType` field on every caller — the job
|
|
42
|
+
* validator, the signing gate and the runner all hold the whole spec.
|
|
43
|
+
*
|
|
44
|
+
* @param {any} closeDecl
|
|
45
|
+
* @param {{at?: string, listing?: string[]|null, deferListing?: boolean,
|
|
46
|
+
* catalogue?: Record<string, any>, verdictType?: string|null}} [opts]
|
|
47
|
+
* @returns {{ok: boolean, reds: Red[], closeDecl: any, grounded: boolean,
|
|
48
|
+
* scoped: {scoped: boolean, via: string|null},
|
|
49
|
+
* ceiling: {class: string, kind: string, stage: string|null, locked: boolean}|null}}
|
|
50
|
+
*/
|
|
51
|
+
export function validateCloseDecl(closeDecl: any, opts?: {
|
|
52
|
+
at?: string;
|
|
53
|
+
listing?: string[] | null;
|
|
54
|
+
deferListing?: boolean;
|
|
55
|
+
catalogue?: Record<string, any>;
|
|
56
|
+
verdictType?: string | null;
|
|
57
|
+
}): {
|
|
58
|
+
ok: boolean;
|
|
59
|
+
reds: Red[];
|
|
60
|
+
closeDecl: any;
|
|
61
|
+
grounded: boolean;
|
|
62
|
+
scoped: {
|
|
63
|
+
scoped: boolean;
|
|
64
|
+
via: string | null;
|
|
65
|
+
};
|
|
66
|
+
ceiling: {
|
|
67
|
+
class: string;
|
|
68
|
+
kind: string;
|
|
69
|
+
stage: string | null;
|
|
70
|
+
locked: boolean;
|
|
71
|
+
} | null;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* The genre's mandatory guard NAMES for a declaration — which stages are D5's
|
|
75
|
+
* guards and which are the job's own work. The seed-verdict read (D9.3) needs
|
|
76
|
+
* exactly this split: `changed-from-seed` is RED at its own seed by
|
|
77
|
+
* construction, so counting it as work would let a close with nothing to do
|
|
78
|
+
* pass the "something must be red at seed" gate.
|
|
79
|
+
* The battery keys off the CLASS the user picked (PRD v1.57 §2), so the class
|
|
80
|
+
* comes in beside the declaration. A class or a language with no battery hands
|
|
81
|
+
* back `[]` — this reads a split, it does not enforce one, and every caller
|
|
82
|
+
* reaches it only after `validateCloseDecl` has already refused both cases.
|
|
83
|
+
* @param {any} closeDecl @param {string} verdictType @returns {string[]}
|
|
84
|
+
*/
|
|
85
|
+
export function guardNames(closeDecl: any, verdictType: string): string[];
|
|
86
|
+
/**
|
|
87
|
+
* Run a DECLARED close (or a check's chain out of one) and return `runClose`'s
|
|
88
|
+
* verdict shape, so every consumer downstream — the precheck, ralph's judge, the
|
|
89
|
+
* `CLOSE_FAULTS` routing, the trend reader, Layer R — is unchanged.
|
|
90
|
+
*
|
|
91
|
+
* The extras a declared close can honestly add ride alongside rather than
|
|
92
|
+
* replacing anything: `declared: true` marks the shape, `value`/`baseline` carry
|
|
93
|
+
* the deciding stage's own measurement, and `trendValue` is the ONE number the
|
|
94
|
+
* trend reader may compare (see the header for why a higher-is-better stage
|
|
95
|
+
* donates none).
|
|
96
|
+
*
|
|
97
|
+
* @param {any[]} stages declared stage descriptors, already validated
|
|
98
|
+
* @param {(s: string) => string} [redact] the scrub, applied at THIS boundary
|
|
99
|
+
* @param {{timeoutMs?: number, cwd?: string, seedRef?: string,
|
|
100
|
+
* seedTrees?: any, gapCap?: number, maxBuffer?: number, baselineMode?: 'auto'|'worktree'}} [opts]
|
|
101
|
+
* @returns {Promise<any>}
|
|
102
|
+
*/
|
|
103
|
+
export function runDeclaredStages(stages: any[], redact?: (s: string) => string, opts?: {
|
|
104
|
+
timeoutMs?: number;
|
|
105
|
+
cwd?: string;
|
|
106
|
+
seedRef?: string;
|
|
107
|
+
seedTrees?: any;
|
|
108
|
+
gapCap?: number;
|
|
109
|
+
maxBuffer?: number;
|
|
110
|
+
baselineMode?: "auto" | "worktree";
|
|
111
|
+
}): Promise<any>;
|
|
112
|
+
/**
|
|
113
|
+
* The trend reader's input for ONE close verdict, whichever executor produced
|
|
114
|
+
* it. A command close hands over its gap and `readGrade` scrapes stage and count
|
|
115
|
+
* out of the text; a declared close already KNOWS both, so it says them instead
|
|
116
|
+
* of round-tripping them through prose it would then have to parse back.
|
|
117
|
+
*
|
|
118
|
+
* Byte-identical to the previous call for a command close: `{ gap }`, with
|
|
119
|
+
* `stage`/`value` left UNDEFINED so `trend.record` falls through to `readGrade`
|
|
120
|
+
* exactly as before. Passing `stage: null` instead would silently disable that
|
|
121
|
+
* fallback — undefined and null are different answers here.
|
|
122
|
+
* @param {any} v a `runClose`-shaped verdict
|
|
123
|
+
* @returns {{gap?: string, stage?: string|null, value?: number|null}}
|
|
124
|
+
*/
|
|
125
|
+
export function closeGrade(v: any): {
|
|
126
|
+
gap?: string;
|
|
127
|
+
stage?: string | null;
|
|
128
|
+
value?: number | null;
|
|
129
|
+
};
|
|
130
|
+
/** @typedef {{code: string, path: string, detail: string, [k: string]: any}} Red */
|
|
131
|
+
/** The genres a `closeDecl` may name. v1 admits exactly one (D13) — a genre
|
|
132
|
+
* classifier is designed the day there is a second genre to classify. */
|
|
133
|
+
export const DECLARED_GENRES: readonly "TYPES"[];
|
|
134
|
+
/**
|
|
135
|
+
* The exact field set of a `closeDecl` — anything else is a smuggle channel, the
|
|
136
|
+
* same rule `STAGE_FIELDS` enforces on a command stage.
|
|
137
|
+
*
|
|
138
|
+
* `genreEnv` is the ARBITER's own record of what it injected (M3's
|
|
139
|
+
* `applyGenreEnv`), and it is here because the injection has to survive being
|
|
140
|
+
* re-read. The flow applies the genre's variable to every env-capable stage
|
|
141
|
+
* AFTER the model's form passed; from then on every re-validation — signing
|
|
142
|
+
* (`prepareSigning`), the job validator (`src/job.js`), the runner
|
|
143
|
+
* (`src/planrun.js`) — sees that key sitting in `params.env` and cannot, from
|
|
144
|
+
* the stage alone, tell our injection from a model-authored guess. Recording it
|
|
145
|
+
* once, in the SIGNED envelope, is what makes the comparison an EQUALITY rather
|
|
146
|
+
* than a presence flag (the same move `checkGuards` makes for guard params), and
|
|
147
|
+
* it is why the model never gets to author it: `authorCloseForJob` composes this
|
|
148
|
+
* field from the flow's own applied map, never from model output. Its keys are
|
|
149
|
+
* constrained to the names the genre OWNS, so it can never become an environment
|
|
150
|
+
* channel of its own.
|
|
151
|
+
*/
|
|
152
|
+
export const CLOSE_DECL_FIELDS: readonly string[];
|
|
153
|
+
/**
|
|
154
|
+
* The prefix M1 puts on EVERY gap line of a declared stage (its `ctx.gapKeep`).
|
|
155
|
+
* A literal, so the anchored pattern below is exact.
|
|
156
|
+
*/
|
|
157
|
+
export const DECLARED_GAP_PREFIX: "close: ";
|
|
158
|
+
/** The `gapKeep` PATTERN for a declared stage, DERIVED from the prefix so the
|
|
159
|
+
* two can never drift. Layer R's red-set and `boundGap`'s keep-block both read
|
|
160
|
+
* it; because every declared line carries the prefix, it designates the stage's
|
|
161
|
+
* whole judged output rather than a hand-picked slice of it. */
|
|
162
|
+
export const DECLARED_GAP_KEEP: string;
|
|
163
|
+
/** The verdict class a DECLARED close may claim. Hard, and by CONSTRUCTION
|
|
164
|
+
* rather than by assertion: every live kind is a mechanical command whose
|
|
165
|
+
* measurement is the truth, and the two judgment kinds are locked out at the
|
|
166
|
+
* catalogue (M2) and absent from the executor (M1). Named as data so the job
|
|
167
|
+
* validator reads one hierarchy table rather than hard-coding a class. */
|
|
168
|
+
export const DECLARED_CLOSE_CLASSES: readonly string[];
|
|
169
|
+
export type Red = {
|
|
170
|
+
code: string;
|
|
171
|
+
path: string;
|
|
172
|
+
detail: string;
|
|
173
|
+
[k: string]: any;
|
|
174
|
+
};
|
package/types/index.d.ts
CHANGED
|
@@ -4,9 +4,17 @@ export { runJob } from "./run.js";
|
|
|
4
4
|
export { ralph, runClose, runStages, CLOSE_FAULTS } from "./ralph.js";
|
|
5
5
|
export { globToPrefix, scanSecrets } from "./validate.js";
|
|
6
6
|
export { validateJob, jobSpecHash, checkApproval, checkMenu, CLOSE_TYPES, CLASS_BY_CLOSE, GOLD_COMPARE, CADENCE_UNITS, PROVIDERS, CONDITION_KEYS, TOOL_MENU, LOCKED_TOOLS, STORE_VERBS, VERDICT_TYPES, LOCKED_VERDICTS } from "./job.js";
|
|
7
|
-
export { validatePlan, stageClose, EXIT_TYPES, MAX_EXITS_PER_STEP, MAX_PLAN_STEPS, WRITE_VERBS } from "./plan.js";
|
|
7
|
+
export { validatePlan, stageClose, EXIT_TYPES, MAX_EXITS_PER_STEP, MAX_PLAN_STEPS, WRITE_VERBS, closeStagesOf } from "./plan.js";
|
|
8
8
|
export { snapshotScope, evalExits } from "./exits.js";
|
|
9
9
|
export { BRIDGE_SCHEMA, validateBridge, deriveStatus, listingRow, loadGate, mintBridge, appendGreen, appendRed, loadBridge, loadRegistry, saveBridge, makeRegistry, registryExists } from "./bridges.js";
|
|
10
10
|
export { renderListing, selectionPrompt } from "./selection.js";
|
|
11
11
|
export { validateEnvelope, resolveTrySpec, resolveReuse, reuseSpecHash, selectBridge, runReuse, REUSE_GRADED_RED, readResume, resumeTreeGate } from "./reuse.js";
|
|
12
12
|
export { classifyIncidents, foldLedger, ledgerDeltas, updateLedger, LEDGER_CLASSES } from "./ledger.js";
|
|
13
|
+
export { workBranchName, prepareWorkBranch, WORK_BRANCH_PREFIX, WORK_BRANCH_RE } from "./workbranch.js";
|
|
14
|
+
export { runDeclaredClose, runStage, seedRead, seedAtHead, seedListing, changedSet, makeSeedTrees, LIVE_KINDS, STOP_FAULTS, JUDGED_MARKER, EXIT_GREEN, EXIT_RED, EXIT_STOP } from "./kinds.js";
|
|
15
|
+
export { validateDeclaration, normalizeDeclaration, KIND_CATALOGUE, CATALOGUE_KINDS, CATALOGUE_LIVE_KINDS, LOCKED_KINDS, TYPES_GENRE, TYPES_GENRE_TEMPLATE, GENRE_LANGUAGES, genreEnv, genreOwnedEnvNames, DIRECTIONS, BASELINES, MAX_STAGES, VERDICT_CLASSES, LOCKED_CLASSES, LIVE_CLASSES, CLASS_BATTERIES, classGuards, closeCeiling } from "./authoring.js";
|
|
16
|
+
export { runAuthorScout, buildSeedListing, seedFileList, classifySurvey, AUTHOR_SCOUT_VERBS, SCOUT_ATTEMPTS, SURVEY_CAUSES, SCOUT_RETRY_CAUSES } from "./authorscout.js";
|
|
17
|
+
export { scrubRaw, RAW_PERSIST_MAX, RAW_TRIM_MARKER } from "./text.js";
|
|
18
|
+
export { authorClose, authorPrompt, declarationSchema, makeLoopGenerate, MAX_REVISIONS, QUESTION_SETS, GREEN_QUESTIONS, CLASS_STATEMENTS, questionsFor, requiredAnswersFor } from "./authorflow.js";
|
|
19
|
+
export { validateCloseDecl, runDeclaredStages, declaredStages, isDeclaredClose, guardNames, closeGrade, DECLARED_GENRES, DECLARED_GAP_PREFIX, DECLARED_GAP_KEEP, DECLARED_CLOSE_CLASSES, CLOSE_DECL_FIELDS } from "./declaredclose.js";
|
|
20
|
+
export { runInterview, authorCloseForJob, assembleSpec, prepareSigning, refusalEvents, refuseLockedKind, GENRE, REFUSAL_LIB, REFUSAL_CATEGORY, AUTHORED_SPEC_FIELDS } from "./authorjob.js";
|
package/types/job.d.ts
CHANGED
|
@@ -93,6 +93,7 @@ export const CLASS_BY_CLOSE: Readonly<{
|
|
|
93
93
|
gold: readonly string[];
|
|
94
94
|
rubric: readonly string[];
|
|
95
95
|
hitl: readonly string[];
|
|
96
|
+
declared: readonly string[];
|
|
96
97
|
}>;
|
|
97
98
|
export const GOLD_COMPARE: readonly string[];
|
|
98
99
|
/** the tool grant menu (2b interview #1): read/grep/write, plus the two litectx
|
package/types/kinds.d.ts
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D8's seed, READ rather than typed: HEAD at run start. A close stores the
|
|
3
|
+
* counting rule and never the number (D12), so which commit the run is measured
|
|
4
|
+
* from is a fact about THIS run — recorded and shown, never carried in a signed
|
|
5
|
+
* spec where it would judge run 5 against run 1's tree.
|
|
6
|
+
*
|
|
7
|
+
* A fault is a named `stop`, never a fallback ref: measuring against the wrong
|
|
8
|
+
* baseline is the failure direction that reads as a clean tree.
|
|
9
|
+
* @param {string} workdir
|
|
10
|
+
* @returns {Promise<{stop: string, seedRef: null}|{stop: null, seedRef: string}>}
|
|
11
|
+
*/
|
|
12
|
+
export function seedAtHead(workdir: string): Promise<{
|
|
13
|
+
stop: string;
|
|
14
|
+
seedRef: null;
|
|
15
|
+
} | {
|
|
16
|
+
stop: null;
|
|
17
|
+
seedRef: string;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* The files that exist AT THE SEED COMMIT. Deliberately not `ls-files`, which
|
|
21
|
+
* reads the index and the working tree: this listing is what a declared path is
|
|
22
|
+
* judged against, and it must describe the tree the close measures from rather
|
|
23
|
+
* than whatever is lying around today.
|
|
24
|
+
*
|
|
25
|
+
* ONE spelling, here beside the other git reads (`src/authorscout.js`'s
|
|
26
|
+
* `seedFileList` delegates to it) — a second listing command is a second
|
|
27
|
+
* instrument, and the one that grades would be the one nobody validated.
|
|
28
|
+
* @param {string} workdir @param {string} seedRef
|
|
29
|
+
* @returns {Promise<{stop: string, files: null}|{stop: null, files: string[]}>}
|
|
30
|
+
*/
|
|
31
|
+
export function seedListing(workdir: string, seedRef: string): Promise<{
|
|
32
|
+
stop: string;
|
|
33
|
+
files: null;
|
|
34
|
+
} | {
|
|
35
|
+
stop: null;
|
|
36
|
+
files: string[];
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* The two arbiter books, and the shape of each exclusion is the whole point.
|
|
40
|
+
*
|
|
41
|
+
* `.litectx/` is a PREFIX — everything beneath the store belongs to the
|
|
42
|
+
* arbiter. `gate-audit.jsonl` is an EXACT repo-relative path and never a
|
|
43
|
+
* basename or a pattern: the gate audit is written to
|
|
44
|
+
* `join(workdir, 'gate-audit.jsonl')` and nowhere else, so a worker-authored
|
|
45
|
+
* `src/gate-audit.jsonl` is NOT an arbiter book and must still count as work.
|
|
46
|
+
* Matching by basename would swallow it — and swallowing a worker's real
|
|
47
|
+
* write is the failure direction that reads as a clean tree.
|
|
48
|
+
* @param {string} rel a repo-relative POSIX path
|
|
49
|
+
* @returns {string|null} the book it belongs to, or null
|
|
50
|
+
*/
|
|
51
|
+
export function isArbiterBook(rel: string): string | null;
|
|
52
|
+
/**
|
|
53
|
+
* Everything this run changed against the seed: the tracked diff PLUS
|
|
54
|
+
* untracked files (an untracked file has no diff — the case a naive
|
|
55
|
+
* `git diff` scan silently misses), minus the arbiter's own books.
|
|
56
|
+
* @param {string} workdir @param {string} seedRef
|
|
57
|
+
* @returns {Promise<{stop: string, fault: string}|{stop: null, paths: string[], tracked: string[], untracked: string[], excluded: {path: string, book: string}[]}>}
|
|
58
|
+
*/
|
|
59
|
+
export function changedSet(workdir: string, seedRef: string): Promise<{
|
|
60
|
+
stop: string;
|
|
61
|
+
fault: string;
|
|
62
|
+
} | {
|
|
63
|
+
stop: null;
|
|
64
|
+
paths: string[];
|
|
65
|
+
tracked: string[];
|
|
66
|
+
untracked: string[];
|
|
67
|
+
excluded: {
|
|
68
|
+
path: string;
|
|
69
|
+
book: string;
|
|
70
|
+
}[];
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* The lines this run ADDED to one file. A tracked file's additions come from
|
|
74
|
+
* its own unified diff; an UNTRACKED file has no diff at all, so its ENTIRE
|
|
75
|
+
* body is added — the half of this primitive a diff-only scan misses.
|
|
76
|
+
* @param {string} workdir @param {string} seedRef @param {string} rel
|
|
77
|
+
* @param {{untracked?: boolean}} [o]
|
|
78
|
+
* @returns {Promise<{stop: string, fault: string}|{stop: null, lines: {n: number, text: string}[], note: string|null}>}
|
|
79
|
+
*/
|
|
80
|
+
export function addedLines(workdir: string, seedRef: string, rel: string, { untracked }?: {
|
|
81
|
+
untracked?: boolean;
|
|
82
|
+
}): Promise<{
|
|
83
|
+
stop: string;
|
|
84
|
+
fault: string;
|
|
85
|
+
} | {
|
|
86
|
+
stop: null;
|
|
87
|
+
lines: {
|
|
88
|
+
n: number;
|
|
89
|
+
text: string;
|
|
90
|
+
}[];
|
|
91
|
+
note: string | null;
|
|
92
|
+
}>;
|
|
93
|
+
/**
|
|
94
|
+
* Count a pattern's capture groups without running it against real input:
|
|
95
|
+
* `src + '|'` always matches the empty string, so the result array's length
|
|
96
|
+
* names the group count. Also the ONE place a declared regex is compiled at
|
|
97
|
+
* validation time, so a broken pattern reds before any process is spawned.
|
|
98
|
+
* @param {any} src
|
|
99
|
+
* @returns {{count: number, red: string|null}}
|
|
100
|
+
*/
|
|
101
|
+
export function regexGroups(src: any): {
|
|
102
|
+
count: number;
|
|
103
|
+
red: string | null;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* THE normalisation of a `count-not-worse` parser (gate-1 amendment #5).
|
|
107
|
+
* The declaration validator and this executor both call it, so there is
|
|
108
|
+
* exactly one spelling of what a parser MEANS — two normalisers that
|
|
109
|
+
* disagree are two instruments, and the one that grades is the one nobody
|
|
110
|
+
* validated.
|
|
111
|
+
*
|
|
112
|
+
* value = Σ over terms of sign × (first | sum of that term's captures,
|
|
113
|
+
* inside that term's region)
|
|
114
|
+
*
|
|
115
|
+
* Backwards compatible by construction: the short form
|
|
116
|
+
* `{lineMatch, capture?}` resolves to exactly one term with
|
|
117
|
+
* `sign +1, aggregate "first", region "whole-output"`, which is the
|
|
118
|
+
* pre-amendment semantics unchanged.
|
|
119
|
+
*
|
|
120
|
+
* Never throws — reds come back in the shipped `{ok, reds, ...}` shape.
|
|
121
|
+
* @param {any} parser @param {string} [at] path prefix for reds
|
|
122
|
+
* @returns {{ok: boolean, reds: Red[], terms: any[]|null}}
|
|
123
|
+
*/
|
|
124
|
+
export function normalizeParser(parser: any, at?: string): {
|
|
125
|
+
ok: boolean;
|
|
126
|
+
reds: Red[];
|
|
127
|
+
terms: any[] | null;
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Read ONE number out of a command's output, as signed arithmetic over
|
|
131
|
+
* normalised terms.
|
|
132
|
+
*
|
|
133
|
+
* The zero-match split is contract (a), not a convenience:
|
|
134
|
+
* - `sum` over zero matches is a COUNTED zero. The region was searched and
|
|
135
|
+
* nothing was there; that is legitimately 0.
|
|
136
|
+
* - `first` over zero matches is UNKNOWN — the number was never reported —
|
|
137
|
+
* and unknown is an instrument stop, never a defaulted 0 (F6).
|
|
138
|
+
* - a region whose anchor matches nothing was never LOCATED: stop.
|
|
139
|
+
* The scope filter runs per OUTPUT LINE, before aggregation, and both its
|
|
140
|
+
* drop count and its unattributable count are ANNOUNCED: a line naming no
|
|
141
|
+
* path is KEPT (no filter can exclude what it cannot locate) and the notes
|
|
142
|
+
* say so, rather than the number quietly meaning something else.
|
|
143
|
+
*
|
|
144
|
+
* `preScopeMatches` is reported alongside the reading because a POST-scope
|
|
145
|
+
* count cannot answer "did the tool run at all". It tallies (term, line) pairs
|
|
146
|
+
* that matched BEFORE the filter judged them — kept, unattributable and dropped
|
|
147
|
+
* alike — and it is the only evidence of liveness a caller has once the scope
|
|
148
|
+
* has removed the whole population. It is never the number being read.
|
|
149
|
+
* @param {string} output @param {any[]} terms normalised terms
|
|
150
|
+
* Every stop here is `crashed` in the arbiter's vocabulary — the command RAN,
|
|
151
|
+
* came back, and the number could not be read out of it. Nothing in this
|
|
152
|
+
* function can observe a spawn failure, a timeout or a signal, so it never
|
|
153
|
+
* claims one.
|
|
154
|
+
* @param {{scope?: any, workdir?: string}} [o]
|
|
155
|
+
* @returns {{stop: string, fault: string, notes?: string[]}|{stop: null, value: number, breakdown: any[], notes: string[], preScopeMatches: number}}
|
|
156
|
+
*/
|
|
157
|
+
export function parseValue(output: string, terms: any[], { scope, workdir }?: {
|
|
158
|
+
scope?: any;
|
|
159
|
+
workdir?: string;
|
|
160
|
+
}): {
|
|
161
|
+
stop: string;
|
|
162
|
+
fault: string;
|
|
163
|
+
notes?: string[];
|
|
164
|
+
} | {
|
|
165
|
+
stop: null;
|
|
166
|
+
value: number;
|
|
167
|
+
breakdown: any[];
|
|
168
|
+
notes: string[];
|
|
169
|
+
preScopeMatches: number;
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* A caller-scoped holder for detached seed worktrees. Scoped rather than
|
|
173
|
+
* module-global on purpose: a global cache in a published library leaks
|
|
174
|
+
* worktrees into whatever process imported it, and nothing would ever remove
|
|
175
|
+
* them. `seedRead`/`runClose` create one, share it across stages (so a
|
|
176
|
+
* multi-stage close pays for one checkout), and remove it in a `finally`.
|
|
177
|
+
* @returns {SeedTrees}
|
|
178
|
+
*/
|
|
179
|
+
export function makeSeedTrees(): SeedTrees;
|
|
180
|
+
/**
|
|
181
|
+
* Run ONE declared stage against a workdir at a seed.
|
|
182
|
+
*
|
|
183
|
+
* It never throws. An unexpected throw inside a kind — a malformed parameter
|
|
184
|
+
* the validator did not catch, an unreachable path — is an INSTRUMENT STOP,
|
|
185
|
+
* not a red: that is the casualty-vs-evidence split at its narrowest, and
|
|
186
|
+
* the direction that matters, because a crash rendered as a red is fake
|
|
187
|
+
* evidence about the worker.
|
|
188
|
+
* @param {any} stage `{name, kind, params}`
|
|
189
|
+
* @param {Ctx} ctx
|
|
190
|
+
* @returns {Promise<StageResult>}
|
|
191
|
+
*/
|
|
192
|
+
export function runStage(stage: any, ctx: Ctx): Promise<StageResult>;
|
|
193
|
+
/**
|
|
194
|
+
* D12's seed-verdict read: run EVERY declared stage at the seed, regardless
|
|
195
|
+
* of reds, and hand back one row per stage.
|
|
196
|
+
*
|
|
197
|
+
* Not first-red-wins, and the reason is structural rather than a preference:
|
|
198
|
+
* every shipped close opens with `changed-from-seed`, which is RED at its own
|
|
199
|
+
* seed by construction (nothing has changed yet), so a first-red-wins seed
|
|
200
|
+
* read measures exactly one stage and mints no baseline for any other. The
|
|
201
|
+
* baseline every `baseline: "seed"` stage is later graded against comes from
|
|
202
|
+
* here, so a stage that never ran is a stage with no bar.
|
|
203
|
+
* @param {any} declaration `{stages: [...]}`
|
|
204
|
+
* @param {Ctx} ctx
|
|
205
|
+
* @returns {Promise<StageResult[]>}
|
|
206
|
+
*/
|
|
207
|
+
export function seedRead(declaration: any, ctx: Ctx): Promise<StageResult[]>;
|
|
208
|
+
/**
|
|
209
|
+
* The GRADING path: stages in declared order, FIRST RED WINS. The deciding
|
|
210
|
+
* stage names the verdict; everything after it is `not-reached` and is
|
|
211
|
+
* reported as such rather than as a green nobody ran.
|
|
212
|
+
*
|
|
213
|
+
* An instrument stop ends the close UNJUDGED — the run has no verdict to
|
|
214
|
+
* carry, which is the whole point of keeping a casualty out of the evidence.
|
|
215
|
+
*
|
|
216
|
+
* NAMED `runDeclaredClose`, not `runClose` (M4's export-surface decision): the
|
|
217
|
+
* arbiter's shell already ships a public `runClose(argv, redact, opts)` that
|
|
218
|
+
* adopters import, and the two take different things and mean different things
|
|
219
|
+
* — one runs a DECLARATION, the other an argv. Renaming the shipped one to make
|
|
220
|
+
* room would break a documented adopter contract for nothing; the new name says
|
|
221
|
+
* exactly what differs. `src/declaredclose.js` is what bridges the two shapes.
|
|
222
|
+
* @param {any} declaration @param {Ctx} ctx
|
|
223
|
+
* @returns {Promise<{verdict: 'green'|'red'|'instrument-stop', exitCode: number, judged: boolean, firstRed: string|null, stages: StageResult[]}>}
|
|
224
|
+
*/
|
|
225
|
+
export function runDeclaredClose(declaration: any, ctx: Ctx): Promise<{
|
|
226
|
+
verdict: "green" | "red" | "instrument-stop";
|
|
227
|
+
exitCode: number;
|
|
228
|
+
judged: boolean;
|
|
229
|
+
firstRed: string | null;
|
|
230
|
+
stages: StageResult[];
|
|
231
|
+
}>;
|
|
232
|
+
/** the close's two judgment exits — a stage's verdict, in the shape the
|
|
233
|
+
* hand-written closes already spoke (exit code is truth) */
|
|
234
|
+
export const EXIT_GREEN: 0;
|
|
235
|
+
export const EXIT_RED: 1;
|
|
236
|
+
/** contract (a): the instrument-stop exit. `judged` is withheld with it. */
|
|
237
|
+
export const EXIT_STOP: 97;
|
|
238
|
+
/** The judgment-rendered marker a rendered close prints, for ralph's
|
|
239
|
+
* `runClose` judged floor (src/ralph.js). It rides EVERY real judgment, green or red,
|
|
240
|
+
* and NEVER a stop — this module reports the same fact as the boolean
|
|
241
|
+
* `judged`; the marker exists so a renderer and the floor agree on one
|
|
242
|
+
* spelling. */
|
|
243
|
+
export const JUDGED_MARKER: "judged=1";
|
|
244
|
+
/** contract (b): the per-stage gap ceiling. Trims are announced, never silent. */
|
|
245
|
+
export const GAP_LINE_CAP: 40;
|
|
246
|
+
/**
|
|
247
|
+
* The exact phrase this executor's trim announcement carries. Exported for the
|
|
248
|
+
* same reason ralph exports `GAP_KEEP_TRIM_MARKER`: Layer R's detector must be
|
|
249
|
+
* able to see that a gap window was TRIMMED, because failures beyond the window
|
|
250
|
+
* can move while the visible lines stay identical — and an undetected trim makes
|
|
251
|
+
* the detector claim "reds unchanged" off an instrument that was blind (F43,
|
|
252
|
+
* finding 5). A magic string on the reading side would drift the day this
|
|
253
|
+
* wording changes; the renderer below is its only other use.
|
|
254
|
+
*/
|
|
255
|
+
export const GAP_TRIM_MARKER: "gap trimmed:";
|
|
256
|
+
/** used when neither the stage nor the ctx names a bound. A stage that could
|
|
257
|
+
* run forever is not a red — it is a stop, and something must decide when. */
|
|
258
|
+
export const DEFAULT_TIMEOUT_MS: 300000;
|
|
259
|
+
/** PER STREAM, like the arbiter's own close runner. An overrun truncates the
|
|
260
|
+
* output mid-summary, so any number read out of it is unknown, not zero. */
|
|
261
|
+
export const MAX_BUFFER: number;
|
|
262
|
+
/** an untracked file larger than this is not scanned line-by-line; the skip
|
|
263
|
+
* is ANNOUNCED in the gap rather than passing as a clean scan */
|
|
264
|
+
export const MAX_SCAN_BYTES: number;
|
|
265
|
+
/** ceiling on a parser's term list — a runaway parser is a red, not a bill */
|
|
266
|
+
export const MAX_TERMS: 8;
|
|
267
|
+
/**
|
|
268
|
+
* WHICH KIND of instrument stop, in the ARBITER's own four-row vocabulary
|
|
269
|
+
* (`CLOSE_FAULTS`, src/ralph.js). Stamped at the site that OBSERVES the fault —
|
|
270
|
+
* never sniffed out of the stop's prose downstream (the typed-attribution rule:
|
|
271
|
+
* a `lib`/fault field is stamped at the throw site, and prose is a fallback for
|
|
272
|
+
* pre-typed spines only).
|
|
273
|
+
*
|
|
274
|
+
* The rows are kept apart for the reason `CLOSE_FAULTS` keeps them apart: they
|
|
275
|
+
* are DIFFERENT HUMAN DECISIONS. "raise the close timeout", "fix the argv" and
|
|
276
|
+
* "re-run, it was OOM-killed" are three answers, and a declared close that
|
|
277
|
+
* pooled all three into `failed` would hand every one of them the same option
|
|
278
|
+
* list. `failed` is the default because "the close cannot run" is the safe
|
|
279
|
+
* reading of a fault nothing else claimed.
|
|
280
|
+
*/
|
|
281
|
+
export const STOP_FAULTS: Readonly<{
|
|
282
|
+
/** the stage cannot RUN at all: spawn failure, a missing seed commit, git refusing */
|
|
283
|
+
FAILED: "failed";
|
|
284
|
+
/** it ran and never finished judging */
|
|
285
|
+
TIMED_OUT: "timed-out";
|
|
286
|
+
/** it died by signal — no opinion was ever rendered */
|
|
287
|
+
KILLED: "killed";
|
|
288
|
+
/** it ran, came back, and judged nothing: unreadable output, a blown buffer,
|
|
289
|
+
* a number that was never reported, a parser that does not normalise */
|
|
290
|
+
CRASHED: "crashed";
|
|
291
|
+
}>;
|
|
292
|
+
export const AGGREGATES: readonly string[];
|
|
293
|
+
export const SIGNS: readonly number[];
|
|
294
|
+
/** every kind this executor implements. `judged-floor` / `human-confirms`
|
|
295
|
+
* are catalogue entries and are deliberately absent here: declaring one is
|
|
296
|
+
* counted demand (the request-red path), and reaching one at runtime is a
|
|
297
|
+
* stop — never a red, and never a silent pass. */
|
|
298
|
+
export const LIVE_KINDS: readonly string[];
|
|
299
|
+
export type Red = {
|
|
300
|
+
code: string;
|
|
301
|
+
path: string;
|
|
302
|
+
detail: string;
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* The arbiter's half of a stage run. Every field here is operator/runner
|
|
306
|
+
* territory: a declaration parameterises kinds, never the contracts.
|
|
307
|
+
*/
|
|
308
|
+
export type Ctx = {
|
|
309
|
+
workdir: string;
|
|
310
|
+
seedRef: string;
|
|
311
|
+
gapKeep: string;
|
|
312
|
+
timeoutMsDefault?: number;
|
|
313
|
+
baselineMode?: "auto" | "worktree";
|
|
314
|
+
gapCap?: number;
|
|
315
|
+
maxBuffer?: number;
|
|
316
|
+
seedTrees?: SeedTrees;
|
|
317
|
+
};
|
|
318
|
+
export type StageResult = {
|
|
319
|
+
verdict: "green" | "red" | "instrument-stop" | "not-reached";
|
|
320
|
+
exitCode: number | null;
|
|
321
|
+
value: number | null;
|
|
322
|
+
baseline: number | null;
|
|
323
|
+
baselineSource: string | null;
|
|
324
|
+
gapLines: string[];
|
|
325
|
+
judged: boolean;
|
|
326
|
+
stage: string | null;
|
|
327
|
+
kind: string | null;
|
|
328
|
+
detail: Record<string, any>;
|
|
329
|
+
};
|
|
330
|
+
export type SeedTrees = {
|
|
331
|
+
ensure: (workdir: string, seedRef: string) => Promise<{
|
|
332
|
+
stop: string;
|
|
333
|
+
fault: string;
|
|
334
|
+
} | {
|
|
335
|
+
stop: null;
|
|
336
|
+
dir: string;
|
|
337
|
+
}>;
|
|
338
|
+
cleanup: () => Promise<{
|
|
339
|
+
ok: boolean;
|
|
340
|
+
leaked: string[];
|
|
341
|
+
detail: string | null;
|
|
342
|
+
}>;
|
|
343
|
+
};
|
package/types/plan.d.ts
CHANGED
|
@@ -48,6 +48,24 @@ export function legalScopes(writeScope: string[], dirs?: string[], cap?: number)
|
|
|
48
48
|
* @returns {any[]|null} the stage list, or null when the close names no command
|
|
49
49
|
*/
|
|
50
50
|
export function stageClose(close: any): any[] | null;
|
|
51
|
+
/**
|
|
52
|
+
* THE ONE STAGING, one level up: a job's close stages, from EITHER of the two
|
|
53
|
+
* fields a spec may carry.
|
|
54
|
+
*
|
|
55
|
+
* `stageClose` reads a command close; `declaredStages` reads an authored
|
|
56
|
+
* declaration (M4). A spec declares exactly one of them — the job validator reds
|
|
57
|
+
* `close-duplicated` on both — so this is a selection, never a merge.
|
|
58
|
+
*
|
|
59
|
+
* Every consumer calls THIS rather than `stageClose` directly, for the reason
|
|
60
|
+
* W4 wrote `stageClose` in the first place: the drafting prompt, the plan
|
|
61
|
+
* validator, the runner, the bridge registry and the reuse envelope must all see
|
|
62
|
+
* the same stage list, and a consumer that reads only `close` sees a declared
|
|
63
|
+
* job as having no close at all — an empty check menu offered to a drafter whose
|
|
64
|
+
* plan the validator would then red for referencing a stage nobody offered.
|
|
65
|
+
* @param {any} job the job spec, any shape
|
|
66
|
+
* @returns {any[]|null} the stage list, or null when the job names no close
|
|
67
|
+
*/
|
|
68
|
+
export function closeStagesOf(job: any): any[] | null;
|
|
51
69
|
/** @typedef {{code: string, path: string, detail?: string, verb?: string}} Red */
|
|
52
70
|
/**
|
|
53
71
|
* Validate an agent-authored plan (`schema: "plan-v1"`) against the SIGNED
|
package/types/planrun.d.ts
CHANGED
|
@@ -252,12 +252,18 @@ export function planPrompt(job: any, scoutBlob: string, reds: any[] | null, maxS
|
|
|
252
252
|
* default; a caller supplies this to drive time deterministically (the same seam `createClock`
|
|
253
253
|
* already exposes — a run's terminal cannot otherwise be exercised without waiting out a cap
|
|
254
254
|
* whose floor is one close timeout).
|
|
255
|
+
* @param {string|null} [opts.resumeBranch] RESUME — the WORK BRANCH the killed leg
|
|
256
|
+
* recorded on its own spine (`readResume`'s `restart.branch`, off the `work-branch`
|
|
257
|
+
* event). With it the resume returns to the branch its own work is sitting on; without
|
|
258
|
+
* it the deterministic name would collide with that very branch and the collision walk
|
|
259
|
+
* would mint a `-2` beside the progress the resume exists to keep. Absent is the cold
|
|
260
|
+
* path. A recorded branch that no longer exists is a STOP, never a fresh start.
|
|
255
261
|
* @returns {Promise<string>} 'green' | 'already-green' | 'escalated' | 'plan-red' |
|
|
256
262
|
* 'check-red' | 'close-red' | 'close-unsupported' | 'recipe-stale' | 'pricing-red' |
|
|
257
|
-
* 'cap-halt' | 'wall-halt' | 'provider-red' | 'interpreter-red' |
|
|
258
|
-
* `step-red:<id>`
|
|
263
|
+
* 'branch-red' | 'cap-halt' | 'wall-halt' | 'provider-red' | 'interpreter-red' |
|
|
264
|
+
* 'step-stalled' | `step-red:<id>`
|
|
259
265
|
*/
|
|
260
|
-
export function runPlan(job: any, { workdir, provider, nativeProvider, providerFor, emit, remainingUsd, isUnpriced, spendComplete, capRuns, strikeLimit, closeTimeoutMs, maxStepRounds, layerRoot, scoutRounds, bridge, now, priorWallMs, resumeSeed, resumeGrades, resumeReplans }: {
|
|
266
|
+
export function runPlan(job: any, { workdir, provider, nativeProvider, providerFor, emit, remainingUsd, isUnpriced, spendComplete, capRuns, strikeLimit, closeTimeoutMs, maxStepRounds, layerRoot, scoutRounds, bridge, now, priorWallMs, resumeSeed, resumeGrades, resumeReplans, resumeBranch }: {
|
|
261
267
|
workdir: string;
|
|
262
268
|
provider: any;
|
|
263
269
|
nativeProvider?: ((o: {
|
|
@@ -289,6 +295,7 @@ export function runPlan(job: any, { workdir, provider, nativeProvider, providerF
|
|
|
289
295
|
} | null | undefined;
|
|
290
296
|
spendComplete?: (() => boolean) | undefined;
|
|
291
297
|
now?: (() => number) | undefined;
|
|
298
|
+
resumeBranch?: string | null | undefined;
|
|
292
299
|
}): Promise<string>;
|
|
293
300
|
export type CategorizedError = Error & {
|
|
294
301
|
category?: string;
|
package/types/ralph.d.ts
CHANGED
|
@@ -272,6 +272,7 @@ export const CLOSE_ENV_DENY: Readonly<{
|
|
|
272
272
|
prefixes: readonly string[];
|
|
273
273
|
shape: RegExp;
|
|
274
274
|
}>;
|
|
275
|
+
export function stageGap(name: string, gap: string): string;
|
|
275
276
|
export const GAP_KEEP_TRIM_MARKER: "more elided by the";
|
|
276
277
|
/**
|
|
277
278
|
* The forbidden zone, named (PRD v1.11). Each row is an outcome in which the
|
package/types/run.d.ts
CHANGED
|
@@ -83,6 +83,13 @@
|
|
|
83
83
|
* RUN's ("unlimited replanning launders thrash as adaptation"). It also rides onto this
|
|
84
84
|
* run's `job-start` as `priorReplans`, the declared-fold precedent `priorSpentUsd`
|
|
85
85
|
* already sets, so a resume OF a resume folds once. Absent is the cold path.
|
|
86
|
+
* @param {string|null} [opts.resumeBranch] RESUME — the WORK BRANCH the killed attempt
|
|
87
|
+
* created and recorded on its own spine (`readResume`'s `restart.branch`). The branch
|
|
88
|
+
* name is DERIVED from the signed spec and is therefore identical on every leg, so
|
|
89
|
+
* without this the restart would collide with its own predecessor's branch and the
|
|
90
|
+
* collision walk would mint a `-2` beside the work the resume exists to continue. The
|
|
91
|
+
* fold's precedent exactly: the chain's state is DECLARED, never re-derived. Forwarded
|
|
92
|
+
* verbatim to the plan flow; absent is the cold path.
|
|
86
93
|
* @param {boolean} [opts.layerRoot=false] Layer R (within-run ratchet) — shell
|
|
87
94
|
* territory, threaded to the plan flow. Defaults OFF
|
|
88
95
|
* (decided 2026-07-21): fixation is extinct on every current job (F41), so
|
|
@@ -92,10 +99,10 @@
|
|
|
92
99
|
* binding.)
|
|
93
100
|
* @returns {Promise<string>} outcome: 'green' | 'already-green' | 'escalated' |
|
|
94
101
|
* 'unapproved-spec' | 'job-red' | 'smoke-red' | 'plan-red' | 'check-red' |
|
|
95
|
-
* 'close-red' | 'close-unsupported' | 'recipe-stale' | 'pricing-red' | 'provider-red' |
|
|
102
|
+
* 'close-red' | 'close-unsupported' | 'recipe-stale' | 'branch-red' | 'pricing-red' | 'provider-red' |
|
|
96
103
|
* 'interpreter-red' | 'cap-halt' | 'wall-halt' | 'step-stalled' | `step-red:<id>`
|
|
97
104
|
*/
|
|
98
|
-
export function runJob(rawSpec: object | string, { approvals, workdir, provider, nativeProvider, providerFor, emit, capRuns, strikeLimit, shellCapUsd, closeTimeoutMs, layerRoot, bridge, priorSpentUsd, priorSpendComplete, priorWallMs, resumeSeed, resumeGrades, resumeReplans }: {
|
|
105
|
+
export function runJob(rawSpec: object | string, { approvals, workdir, provider, nativeProvider, providerFor, emit, capRuns, strikeLimit, shellCapUsd, closeTimeoutMs, layerRoot, bridge, priorSpentUsd, priorSpendComplete, priorWallMs, resumeSeed, resumeGrades, resumeReplans, resumeBranch }: {
|
|
99
106
|
approvals: unknown;
|
|
100
107
|
workdir: string;
|
|
101
108
|
provider: any;
|
|
@@ -124,6 +131,7 @@ export function runJob(rawSpec: object | string, { approvals, workdir, provider,
|
|
|
124
131
|
count?: number;
|
|
125
132
|
grantUsed?: boolean;
|
|
126
133
|
} | null | undefined;
|
|
134
|
+
resumeBranch?: string | null | undefined;
|
|
127
135
|
layerRoot?: boolean | undefined;
|
|
128
136
|
}): Promise<string>;
|
|
129
137
|
export type Red = {
|