@deftai/directive-core 0.100.0 → 0.101.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/dist/authz/classify.js +100 -23
- package/dist/authz/decompose-apply.d.ts +14 -0
- package/dist/authz/decompose-apply.js +93 -18
- package/dist/check/cached-orchestrator.d.ts +26 -5
- package/dist/check/cached-orchestrator.js +228 -6
- package/dist/check/gate-lists.d.ts +10 -4
- package/dist/check/gate-lists.js +19 -5
- package/dist/check/index.d.ts +3 -2
- package/dist/check/index.js +2 -1
- package/dist/check/named-cause.d.ts +45 -0
- package/dist/check/named-cause.js +121 -0
- package/dist/check/orchestrator.js +6 -1
- package/dist/doctor/help.d.ts +5 -0
- package/dist/doctor/help.js +31 -0
- package/dist/doctor/index.d.ts +2 -0
- package/dist/doctor/index.js +2 -0
- package/dist/doctor/main.js +58 -0
- package/dist/doctor/session-coda.d.ts +82 -0
- package/dist/doctor/session-coda.js +151 -0
- package/dist/doctor/types.d.ts +16 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/init-deposit/gitignore.js +2 -0
- package/dist/intake/issue-ingest.js +7 -0
- package/dist/policy/ac-pass-banking.d.ts +58 -0
- package/dist/policy/ac-pass-banking.js +150 -0
- package/dist/policy/ceremony-dial.d.ts +29 -0
- package/dist/policy/ceremony-dial.js +76 -0
- package/dist/policy/index.d.ts +1 -0
- package/dist/policy/index.js +15 -1
- package/dist/preflight-cache/evaluate.d.ts +3 -0
- package/dist/preflight-cache/evaluate.js +3 -0
- package/dist/product-first-done-gate/acceptance.d.ts +25 -0
- package/dist/product-first-done-gate/acceptance.js +247 -0
- package/dist/product-first-done-gate/check-mode.d.ts +45 -0
- package/dist/product-first-done-gate/check-mode.js +148 -0
- package/dist/product-first-done-gate/evaluate.d.ts +50 -0
- package/dist/product-first-done-gate/evaluate.js +255 -0
- package/dist/product-first-done-gate/index.d.ts +11 -0
- package/dist/product-first-done-gate/index.js +11 -0
- package/dist/product-first-done-gate/types.d.ts +64 -0
- package/dist/product-first-done-gate/types.js +61 -0
- package/dist/run-summary/emit.d.ts +56 -0
- package/dist/run-summary/emit.js +171 -0
- package/dist/run-summary/index.d.ts +4 -0
- package/dist/run-summary/index.js +4 -0
- package/dist/run-summary/path.d.ts +25 -0
- package/dist/run-summary/path.js +78 -0
- package/dist/run-summary/types.d.ts +76 -0
- package/dist/run-summary/types.js +21 -0
- package/dist/scope/acceptance-evidence.d.ts +34 -0
- package/dist/scope/acceptance-evidence.js +84 -10
- package/dist/scope/decompose.d.ts +5 -0
- package/dist/scope/decompose.js +11 -2
- package/dist/session/ac-pass-banking.d.ts +221 -0
- package/dist/session/ac-pass-banking.js +761 -0
- package/dist/session/deposit-sha.d.ts +49 -0
- package/dist/session/deposit-sha.js +121 -0
- package/dist/session/effort-budget.d.ts +6 -0
- package/dist/session/effort-budget.js +21 -3
- package/dist/session/index.d.ts +5 -0
- package/dist/session/index.js +5 -0
- package/dist/session/orientation-compression.d.ts +127 -0
- package/dist/session/orientation-compression.js +425 -0
- package/dist/session/orientation-state.d.ts +29 -0
- package/dist/session/orientation-state.js +85 -0
- package/dist/session/session-start.d.ts +25 -0
- package/dist/session/session-start.js +175 -0
- package/dist/session/toolchain-preflight.d.ts +64 -0
- package/dist/session/toolchain-preflight.js +151 -0
- package/dist/triage/bootstrap/gitignore.d.ts +1 -1
- package/dist/triage/bootstrap/gitignore.js +8 -2
- package/dist/triage/bootstrap/index.js +15 -3
- package/dist/triage/classify/index.d.ts +1 -0
- package/dist/triage/classify/index.js +2 -0
- package/dist/triage/classify/label-mirror.js +16 -0
- package/dist/triage/classify/mirror-discovery-tip.d.ts +95 -0
- package/dist/triage/classify/mirror-discovery-tip.js +234 -0
- package/dist/triage/reconcile/reconcile.js +28 -6
- package/dist/triage/summary/index.js +12 -4
- package/dist/triage/welcome/default-mode.js +16 -0
- package/dist/ts-check-lane/run-lane.js +21 -4
- package/dist/vbrief-validate/conformance.js +7 -0
- package/dist/vitest-runner/coverage-debt-teardown.js +16 -4
- package/package.json +11 -3
package/dist/doctor/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * from "./checks.js";
|
|
|
3
3
|
export * from "./constants.js";
|
|
4
4
|
export * from "./doctor-state.js";
|
|
5
5
|
export * from "./flags.js";
|
|
6
|
+
export * from "./help.js";
|
|
6
7
|
export * from "./json.js";
|
|
7
8
|
export * from "./main.js";
|
|
8
9
|
export * from "./manifest.js";
|
|
@@ -13,6 +14,7 @@ export * from "./openclaw-soft-rebind.js";
|
|
|
13
14
|
export * from "./paths.js";
|
|
14
15
|
export * from "./payload-staleness.js";
|
|
15
16
|
export * from "./release-availability.js";
|
|
17
|
+
export * from "./session-coda.js";
|
|
16
18
|
export * from "./taskfile.js";
|
|
17
19
|
export * from "./types.js";
|
|
18
20
|
export * from "./which.js";
|
package/dist/doctor/main.js
CHANGED
|
@@ -16,6 +16,7 @@ import { checkXbriefEnvelopeMajorVersion, runChecks, XBRIEF_ENVELOPE_MAJOR_CHECK
|
|
|
16
16
|
import { CONSUMER_FRAMEWORK_DIRS, EXPECTED_CONTENT_DIRS, EXPECTED_FRAMEWORK_DIRS, NETWORK_DISCLOSURE_LINE, PAYLOAD_STALENESS_OFFLINE_SKIP_MESSAGE, TASKFILE_INCLUDE_SNIPPET, UV_INSTALL_URL, } from "./constants.js";
|
|
17
17
|
import { decideThrottle, formatIsoZ, readState, renderDoctorStatusLine, writeState, } from "./doctor-state.js";
|
|
18
18
|
import { formatAllowedFlagsHint, formatUnknownFlagsError, parseDoctorFlags } from "./flags.js";
|
|
19
|
+
import { formatDoctorHelp } from "./help.js";
|
|
19
20
|
import { pythonJsonDump } from "./json.js";
|
|
20
21
|
import { parseInstallRootFromAgentsMd } from "./manifest.js";
|
|
21
22
|
import { runNpmRegistryMirrorCheck } from "./npm-registry.js";
|
|
@@ -25,6 +26,7 @@ import { runOpenClawSoftRebindCheck } from "./openclaw-soft-rebind.js";
|
|
|
25
26
|
import { createPlainSink } from "./output.js";
|
|
26
27
|
import { readTextSafe, resolveFrameworkRootForProject, resolvePath, resolveVersion, runningInsideDeftRepo, } from "./paths.js";
|
|
27
28
|
import { runPayloadStalenessCheck } from "./payload-staleness.js";
|
|
29
|
+
import { loadSessionCodas, projectRootRealpath, resolveSessionCodaLine, SESSION_CODA_ENV, sessionCodaMode, shouldEmitSessionCodaLine, utcDateYmd, } from "./session-coda.js";
|
|
28
30
|
import { runLocalSignpostChecks } from "./signpost-checks.js";
|
|
29
31
|
import { classifyTaskfileInclude, formatGatesSurfaceDualRemediation, formatMissingIncludeSnippet, GATES_SURFACE_DEFT_REMEDIATION, includesBlockHasDeftTaskfile, resolveConsumerTaskfile, } from "./taskfile.js";
|
|
30
32
|
import { defaultWhich } from "./which.js";
|
|
@@ -58,6 +60,10 @@ export function cmdDoctor(args, seams = {}) {
|
|
|
58
60
|
sink.info(formatAllowedFlagsHint());
|
|
59
61
|
return 2;
|
|
60
62
|
}
|
|
63
|
+
if (flags.help) {
|
|
64
|
+
process.stdout.write(formatDoctorHelp());
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
61
67
|
const sessionMode = flags.session;
|
|
62
68
|
const fixMode = flags.fix && !sessionMode;
|
|
63
69
|
const jsonMode = flags.json;
|
|
@@ -489,6 +495,15 @@ export function cmdDoctor(args, seams = {}) {
|
|
|
489
495
|
sink.blank();
|
|
490
496
|
if (errorCount === 0 && warningCount === 0) {
|
|
491
497
|
sink.finalSuccess("System check passed!");
|
|
498
|
+
emitSessionCodaAfterFinalSuccess({
|
|
499
|
+
projectRoot,
|
|
500
|
+
frameworkRoot,
|
|
501
|
+
jsonMode,
|
|
502
|
+
exitOk: true,
|
|
503
|
+
now: nowFn(),
|
|
504
|
+
seams,
|
|
505
|
+
sink,
|
|
506
|
+
});
|
|
492
507
|
return 0;
|
|
493
508
|
}
|
|
494
509
|
if (errorCount) {
|
|
@@ -498,8 +513,51 @@ export function cmdDoctor(args, seams = {}) {
|
|
|
498
513
|
return 1;
|
|
499
514
|
}
|
|
500
515
|
sink.finalWarn(`System check completed with ${warningCount} warning(s).`);
|
|
516
|
+
emitSessionCodaAfterFinalSuccess({
|
|
517
|
+
projectRoot,
|
|
518
|
+
frameworkRoot,
|
|
519
|
+
jsonMode,
|
|
520
|
+
exitOk: true,
|
|
521
|
+
now: nowFn(),
|
|
522
|
+
seams,
|
|
523
|
+
sink,
|
|
524
|
+
});
|
|
501
525
|
return 0;
|
|
502
526
|
}
|
|
527
|
+
/**
|
|
528
|
+
* After the final human success footer only (D2): optional off-hint or ✦ coda.
|
|
529
|
+
* Never mid-run Next command: block; never JSON; never hard-fail path (D1).
|
|
530
|
+
*/
|
|
531
|
+
function emitSessionCodaAfterFinalSuccess(input) {
|
|
532
|
+
const stdoutIsTty = input.seams.stdoutIsTty ?? (() => process.stdout.isTTY === true);
|
|
533
|
+
// `in` so tests can force unset via `{ sessionCodaEnv: undefined }` without
|
|
534
|
+
// leaking the host process env.
|
|
535
|
+
const envRaw = "sessionCodaEnv" in input.seams ? input.seams.sessionCodaEnv : process.env[SESSION_CODA_ENV];
|
|
536
|
+
const ciRaw = "ciEnv" in input.seams ? input.seams.ciEnv : process.env.CI;
|
|
537
|
+
const ci = Boolean(ciRaw && ciRaw !== "0" && String(ciRaw).toLowerCase() !== "false");
|
|
538
|
+
const shouldEmit = shouldEmitSessionCodaLine({
|
|
539
|
+
tty: stdoutIsTty(),
|
|
540
|
+
ci,
|
|
541
|
+
json: input.jsonMode,
|
|
542
|
+
exitOk: input.exitOk,
|
|
543
|
+
});
|
|
544
|
+
const mode = sessionCodaMode(envRaw);
|
|
545
|
+
const codas = mode === "on"
|
|
546
|
+
? (input.seams.loadSessionCodas?.(input.frameworkRoot) ??
|
|
547
|
+
loadSessionCodas(input.frameworkRoot, input.seams.readText))
|
|
548
|
+
: [];
|
|
549
|
+
const line = resolveSessionCodaLine({
|
|
550
|
+
mode,
|
|
551
|
+
shouldEmit,
|
|
552
|
+
date: utcDateYmd(input.now),
|
|
553
|
+
projectRoot: projectRootRealpath(input.projectRoot),
|
|
554
|
+
codas,
|
|
555
|
+
});
|
|
556
|
+
if (line === null)
|
|
557
|
+
return;
|
|
558
|
+
input.sink.blank();
|
|
559
|
+
input.sink.raw(line);
|
|
560
|
+
}
|
|
503
561
|
export function runAgentHooksHealthCheck(projectRoot, consumerContext, sink, addFinding, seams) {
|
|
504
562
|
const checkName = "agent-hooks-registration";
|
|
505
563
|
if (!consumerContext) {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional deterministic session coda for interactive doctor success (#2712).
|
|
3
|
+
*
|
|
4
|
+
* Human TTY affordance only: never JSON, never AGENTS/skills, never exit-code
|
|
5
|
+
* changes. Env three-state DEFT_SESSION_CODA (unset / 1 / 0). Copy lives in
|
|
6
|
+
* content/doctor/session-coda.json — not embedded as an engine literal.
|
|
7
|
+
*/
|
|
8
|
+
/** Env var name (env-only v1; no USER.md key). */
|
|
9
|
+
export declare const SESSION_CODA_ENV = "DEFT_SESSION_CODA";
|
|
10
|
+
/**
|
|
11
|
+
* Fixed discoverability line when env is unset and gates pass (D3).
|
|
12
|
+
* Snapshot-stable; not selected from the pack; no ✦ prefix.
|
|
13
|
+
*/
|
|
14
|
+
export declare const SESSION_CODA_OFF_HINT = "Session coda: off (set DEFT_SESSION_CODA=1 to enable)";
|
|
15
|
+
/** U+2726 FOUR RAYED STAR + space — stable; do not localize. */
|
|
16
|
+
export declare const SESSION_CODA_STAR_PREFIX = "\u2726 ";
|
|
17
|
+
/** Max body length; longer pack entries are skipped (fail-open). */
|
|
18
|
+
export declare const SESSION_CODA_MAX_CHARS = 100;
|
|
19
|
+
/** Relative path under contentRoot (source: content/doctor/…; deposit: doctor/…). */
|
|
20
|
+
export declare const SESSION_CODA_REL_PATH: string;
|
|
21
|
+
export type SessionCodaMode = "unset" | "on" | "off";
|
|
22
|
+
/**
|
|
23
|
+
* Map DEFT_SESSION_CODA to the three-state mode (D3).
|
|
24
|
+
* - undefined / "" → unset (discoverability off-hint)
|
|
25
|
+
* - "1" → on (✦ coda)
|
|
26
|
+
* - "0" → off (silent)
|
|
27
|
+
* - any other non-empty value → unset (show correct enable form)
|
|
28
|
+
*/
|
|
29
|
+
export declare function sessionCodaMode(envValue: string | undefined): SessionCodaMode;
|
|
30
|
+
/**
|
|
31
|
+
* Whether any extra line (off-hint or coda) is allowed (D1 + surface gates).
|
|
32
|
+
* TTY = stdout.isTTY; CI truthy blocks; json blocks; exitOk = errorCount === 0.
|
|
33
|
+
*/
|
|
34
|
+
export declare function shouldEmitSessionCodaLine(input: {
|
|
35
|
+
readonly tty: boolean;
|
|
36
|
+
readonly ci: boolean;
|
|
37
|
+
readonly json: boolean;
|
|
38
|
+
readonly exitOk: boolean;
|
|
39
|
+
}): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* FNV-1a 32-bit (#2712). Documented choice for hash_u32(date + "\\0" + root).
|
|
42
|
+
* No Math.random; same inputs ⇒ same u32 on every platform.
|
|
43
|
+
*/
|
|
44
|
+
export declare function hashU32(input: string): number;
|
|
45
|
+
/** UTC calendar date yyyy-mm-dd from a Date (stable for 24h across a team day). */
|
|
46
|
+
export declare function utcDateYmd(date: Date): string;
|
|
47
|
+
/** Best-effort realpath; falls back to the given path when realpath fails. */
|
|
48
|
+
export declare function projectRootRealpath(projectRoot: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Select one coda body from the pack (enabled path only).
|
|
51
|
+
* index = hash_u32(utc_date + "\\0" + project_root_realpath) % len(codas)
|
|
52
|
+
* Empty list → null (omit ✦; doctor still 0).
|
|
53
|
+
*/
|
|
54
|
+
export declare function selectSessionCoda(input: {
|
|
55
|
+
readonly date: string;
|
|
56
|
+
readonly projectRoot: string;
|
|
57
|
+
readonly codas: readonly string[];
|
|
58
|
+
}): string | null;
|
|
59
|
+
/** Skip non-strings and bodies over SESSION_CODA_MAX_CHARS. */
|
|
60
|
+
export declare function filterCodaEntries(raw: unknown): string[];
|
|
61
|
+
/**
|
|
62
|
+
* Load + filter coda lines from content. Fail-open: missing/unreadable/invalid
|
|
63
|
+
* / empty after filter → [] (omit ✦; no error noise).
|
|
64
|
+
*/
|
|
65
|
+
export declare function loadSessionCodas(frameworkRoot: string, readText?: (path: string) => string | null): string[];
|
|
66
|
+
/** Format enabled coda line: ✦ + space + body. */
|
|
67
|
+
export declare function formatSessionCodaEnabledLine(body: string): string;
|
|
68
|
+
export interface ResolveSessionCodaLineInput {
|
|
69
|
+
readonly mode: SessionCodaMode;
|
|
70
|
+
readonly shouldEmit: boolean;
|
|
71
|
+
readonly date: string;
|
|
72
|
+
readonly projectRoot: string;
|
|
73
|
+
readonly codas: readonly string[];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolve the single extra line (or null) after final success footer.
|
|
77
|
+
* Does not print; caller places after blank line post footer (D2).
|
|
78
|
+
*/
|
|
79
|
+
export declare function resolveSessionCodaLine(input: ResolveSessionCodaLineInput): string | null;
|
|
80
|
+
/** Help / env-docs fragment for DEFT_SESSION_CODA three-state (#2712). */
|
|
81
|
+
export declare function sessionCodaHelpText(): string;
|
|
82
|
+
//# sourceMappingURL=session-coda.d.ts.map
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional deterministic session coda for interactive doctor success (#2712).
|
|
3
|
+
*
|
|
4
|
+
* Human TTY affordance only: never JSON, never AGENTS/skills, never exit-code
|
|
5
|
+
* changes. Env three-state DEFT_SESSION_CODA (unset / 1 / 0). Copy lives in
|
|
6
|
+
* content/doctor/session-coda.json — not embedded as an engine literal.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, realpathSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { contentRoot } from "../content-root.js";
|
|
11
|
+
/** Env var name (env-only v1; no USER.md key). */
|
|
12
|
+
export const SESSION_CODA_ENV = "DEFT_SESSION_CODA";
|
|
13
|
+
/**
|
|
14
|
+
* Fixed discoverability line when env is unset and gates pass (D3).
|
|
15
|
+
* Snapshot-stable; not selected from the pack; no ✦ prefix.
|
|
16
|
+
*/
|
|
17
|
+
export const SESSION_CODA_OFF_HINT = "Session coda: off (set DEFT_SESSION_CODA=1 to enable)";
|
|
18
|
+
/** U+2726 FOUR RAYED STAR + space — stable; do not localize. */
|
|
19
|
+
export const SESSION_CODA_STAR_PREFIX = "\u2726 ";
|
|
20
|
+
/** Max body length; longer pack entries are skipped (fail-open). */
|
|
21
|
+
export const SESSION_CODA_MAX_CHARS = 100;
|
|
22
|
+
/** Relative path under contentRoot (source: content/doctor/…; deposit: doctor/…). */
|
|
23
|
+
export const SESSION_CODA_REL_PATH = join("doctor", "session-coda.json");
|
|
24
|
+
/**
|
|
25
|
+
* Map DEFT_SESSION_CODA to the three-state mode (D3).
|
|
26
|
+
* - undefined / "" → unset (discoverability off-hint)
|
|
27
|
+
* - "1" → on (✦ coda)
|
|
28
|
+
* - "0" → off (silent)
|
|
29
|
+
* - any other non-empty value → unset (show correct enable form)
|
|
30
|
+
*/
|
|
31
|
+
export function sessionCodaMode(envValue) {
|
|
32
|
+
if (envValue === undefined || envValue === "")
|
|
33
|
+
return "unset";
|
|
34
|
+
if (envValue === "1")
|
|
35
|
+
return "on";
|
|
36
|
+
if (envValue === "0")
|
|
37
|
+
return "off";
|
|
38
|
+
return "unset";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Whether any extra line (off-hint or coda) is allowed (D1 + surface gates).
|
|
42
|
+
* TTY = stdout.isTTY; CI truthy blocks; json blocks; exitOk = errorCount === 0.
|
|
43
|
+
*/
|
|
44
|
+
export function shouldEmitSessionCodaLine(input) {
|
|
45
|
+
return input.exitOk === true && input.tty === true && input.ci !== true && input.json !== true;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* FNV-1a 32-bit (#2712). Documented choice for hash_u32(date + "\\0" + root).
|
|
49
|
+
* No Math.random; same inputs ⇒ same u32 on every platform.
|
|
50
|
+
*/
|
|
51
|
+
export function hashU32(input) {
|
|
52
|
+
let hash = 0x811c9dc5;
|
|
53
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
54
|
+
hash ^= input.charCodeAt(i);
|
|
55
|
+
hash = Math.imul(hash, 0x01000193);
|
|
56
|
+
}
|
|
57
|
+
return hash >>> 0;
|
|
58
|
+
}
|
|
59
|
+
/** UTC calendar date yyyy-mm-dd from a Date (stable for 24h across a team day). */
|
|
60
|
+
export function utcDateYmd(date) {
|
|
61
|
+
return date.toISOString().slice(0, 10);
|
|
62
|
+
}
|
|
63
|
+
/** Best-effort realpath; falls back to the given path when realpath fails. */
|
|
64
|
+
export function projectRootRealpath(projectRoot) {
|
|
65
|
+
try {
|
|
66
|
+
return realpathSync(projectRoot);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return projectRoot;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Select one coda body from the pack (enabled path only).
|
|
74
|
+
* index = hash_u32(utc_date + "\\0" + project_root_realpath) % len(codas)
|
|
75
|
+
* Empty list → null (omit ✦; doctor still 0).
|
|
76
|
+
*/
|
|
77
|
+
export function selectSessionCoda(input) {
|
|
78
|
+
const { date, projectRoot, codas } = input;
|
|
79
|
+
if (codas.length === 0)
|
|
80
|
+
return null;
|
|
81
|
+
const key = `${date}\0${projectRoot}`;
|
|
82
|
+
const index = hashU32(key) % codas.length;
|
|
83
|
+
return codas[index] ?? null;
|
|
84
|
+
}
|
|
85
|
+
/** Skip non-strings and bodies over SESSION_CODA_MAX_CHARS. */
|
|
86
|
+
export function filterCodaEntries(raw) {
|
|
87
|
+
if (!Array.isArray(raw))
|
|
88
|
+
return [];
|
|
89
|
+
const out = [];
|
|
90
|
+
for (const entry of raw) {
|
|
91
|
+
if (typeof entry !== "string")
|
|
92
|
+
continue;
|
|
93
|
+
if (entry.length === 0 || entry.length > SESSION_CODA_MAX_CHARS)
|
|
94
|
+
continue;
|
|
95
|
+
out.push(entry);
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Load + filter coda lines from content. Fail-open: missing/unreadable/invalid
|
|
101
|
+
* / empty after filter → [] (omit ✦; no error noise).
|
|
102
|
+
*/
|
|
103
|
+
export function loadSessionCodas(frameworkRoot, readText) {
|
|
104
|
+
const packPath = join(contentRoot(frameworkRoot), SESSION_CODA_REL_PATH);
|
|
105
|
+
try {
|
|
106
|
+
const text = readText !== undefined ? readText(packPath) : readFileSync(packPath, { encoding: "utf8" });
|
|
107
|
+
if (text === null || text === "")
|
|
108
|
+
return [];
|
|
109
|
+
return filterCodaEntries(JSON.parse(text));
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Format enabled coda line: ✦ + space + body. */
|
|
116
|
+
export function formatSessionCodaEnabledLine(body) {
|
|
117
|
+
return `${SESSION_CODA_STAR_PREFIX}${body}`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Resolve the single extra line (or null) after final success footer.
|
|
121
|
+
* Does not print; caller places after blank line post footer (D2).
|
|
122
|
+
*/
|
|
123
|
+
export function resolveSessionCodaLine(input) {
|
|
124
|
+
if (!input.shouldEmit)
|
|
125
|
+
return null;
|
|
126
|
+
if (input.mode === "off")
|
|
127
|
+
return null;
|
|
128
|
+
if (input.mode === "unset")
|
|
129
|
+
return SESSION_CODA_OFF_HINT;
|
|
130
|
+
const body = selectSessionCoda({
|
|
131
|
+
date: input.date,
|
|
132
|
+
projectRoot: input.projectRoot,
|
|
133
|
+
codas: input.codas,
|
|
134
|
+
});
|
|
135
|
+
if (body === null)
|
|
136
|
+
return null;
|
|
137
|
+
return formatSessionCodaEnabledLine(body);
|
|
138
|
+
}
|
|
139
|
+
/** Help / env-docs fragment for DEFT_SESSION_CODA three-state (#2712). */
|
|
140
|
+
export function sessionCodaHelpText() {
|
|
141
|
+
return [
|
|
142
|
+
"Environment:",
|
|
143
|
+
` ${SESSION_CODA_ENV} Session coda after interactive success (exit 0, TTY, not CI, not --json):`,
|
|
144
|
+
" unset Print discoverability line:",
|
|
145
|
+
` ${SESSION_CODA_OFF_HINT}`,
|
|
146
|
+
" =1 Print one curated line, e.g.:",
|
|
147
|
+
` ${formatSessionCodaEnabledLine("Doctor first. Then continue.")}`,
|
|
148
|
+
" =0 Silent (no hint, no coda)",
|
|
149
|
+
].join("\n");
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=session-coda.js.map
|
package/dist/doctor/types.d.ts
CHANGED
|
@@ -123,6 +123,22 @@ export interface DoctorSeams {
|
|
|
123
123
|
now?: Date;
|
|
124
124
|
}) => string | null;
|
|
125
125
|
readonly isTty?: () => boolean;
|
|
126
|
+
/**
|
|
127
|
+
* stdout TTY probe for session coda (#2712). Defaults to
|
|
128
|
+
* `process.stdout.isTTY === true` (not stdin). Separate from `isTty` (stdin
|
|
129
|
+
* used by --fix prompts).
|
|
130
|
+
*/
|
|
131
|
+
readonly stdoutIsTty?: () => boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Override DEFT_SESSION_CODA for tests (#2712). `undefined` means read
|
|
134
|
+
* process.env; pass `""` or omit via explicit nullish env simulation with
|
|
135
|
+
* `undefined` from a seam that returns undefined.
|
|
136
|
+
*/
|
|
137
|
+
readonly sessionCodaEnv?: string | undefined;
|
|
138
|
+
/** Override CI env string for session coda gates (#2712). */
|
|
139
|
+
readonly ciEnv?: string | undefined;
|
|
140
|
+
/** Override session-coda pack loader for fail-open tests (#2712). */
|
|
141
|
+
readonly loadSessionCodas?: (frameworkRoot: string) => string[];
|
|
126
142
|
readonly readYn?: (prompt: string, defaultYes: boolean) => boolean;
|
|
127
143
|
readonly writeText?: (path: string, content: string) => void;
|
|
128
144
|
readonly now?: () => Date;
|
package/dist/index.d.ts
CHANGED
|
@@ -48,12 +48,14 @@ export * as prMonitor from "./pr-monitor/index.js";
|
|
|
48
48
|
export * as prProtectedIssues from "./pr-protected-issues/index.js";
|
|
49
49
|
export * as prWaitMergeable from "./pr-wait-mergeable/index.js";
|
|
50
50
|
export * as preflight from "./preflight/index.js";
|
|
51
|
+
export * as productFirstDoneGate from "./product-first-done-gate/index.js";
|
|
51
52
|
export * as release from "./release/index.js";
|
|
52
53
|
export * as releaseE2e from "./release-e2e/index.js";
|
|
53
54
|
export * as releasePublish from "./release-publish/index.js";
|
|
54
55
|
export * as releaseRollback from "./release-rollback/index.js";
|
|
55
56
|
export * as render from "./render/index.js";
|
|
56
57
|
export * as resolution from "./resolution/index.js";
|
|
58
|
+
export * as runSummary from "./run-summary/index.js";
|
|
57
59
|
export * as scm from "./scm/index.js";
|
|
58
60
|
export * as scope from "./scope/index.js";
|
|
59
61
|
export * as scopeProvenance from "./scope-provenance/index.js";
|
package/dist/index.js
CHANGED
|
@@ -49,12 +49,14 @@ export * as prMonitor from "./pr-monitor/index.js";
|
|
|
49
49
|
export * as prProtectedIssues from "./pr-protected-issues/index.js";
|
|
50
50
|
export * as prWaitMergeable from "./pr-wait-mergeable/index.js";
|
|
51
51
|
export * as preflight from "./preflight/index.js";
|
|
52
|
+
export * as productFirstDoneGate from "./product-first-done-gate/index.js";
|
|
52
53
|
export * as release from "./release/index.js";
|
|
53
54
|
export * as releaseE2e from "./release-e2e/index.js";
|
|
54
55
|
export * as releasePublish from "./release-publish/index.js";
|
|
55
56
|
export * as releaseRollback from "./release-rollback/index.js";
|
|
56
57
|
export * as render from "./render/index.js";
|
|
57
58
|
export * as resolution from "./resolution/index.js";
|
|
59
|
+
export * as runSummary from "./run-summary/index.js";
|
|
58
60
|
export * as scm from "./scm/index.js";
|
|
59
61
|
export * as scope from "./scope/index.js";
|
|
60
62
|
export * as scopeProvenance from "./scope-provenance/index.js";
|
|
@@ -30,6 +30,8 @@ export const CANONICAL_GITIGNORE_BASELINE = [
|
|
|
30
30
|
".deft/ritual-state.json",
|
|
31
31
|
".deft/last-session.json",
|
|
32
32
|
".deft/routing.local.json",
|
|
33
|
+
// #3282: opt-in default run-summary JSONL at repo root (collectible; must not dirty trees).
|
|
34
|
+
".deft-run-summary.json",
|
|
33
35
|
// Temporary test/local kill-switch — must stay untracked (#3039).
|
|
34
36
|
DEFT_DIRECTIVE_DISABLE_GITIGNORE_LINE,
|
|
35
37
|
"vbrief/.triage-cache/candidates.jsonl",
|
|
@@ -5,6 +5,7 @@ import { scan } from "../cache/scanner.js";
|
|
|
5
5
|
import { assertWriteTargetSafe, ProjectionContainmentError } from "../fs/projection-containment.js";
|
|
6
6
|
import { hasArtifactSuffix, resolveLifecycleRoot } from "../layout/resolve.js";
|
|
7
7
|
import { captureAndAttachLiteralAcceptance } from "../literal-acceptance/index.js";
|
|
8
|
+
import { stampAcceptanceFromLiteralCapture } from "../product-first-done-gate/index.js";
|
|
8
9
|
import { call } from "../scm/call.js";
|
|
9
10
|
import { resolveProjectRoot } from "../scope/project-context.js";
|
|
10
11
|
import { resolveProjectRepo } from "../slice/project-context.js";
|
|
@@ -472,6 +473,12 @@ export function buildIssueVbrief(issue, status, repoUrl, options = {}) {
|
|
|
472
473
|
}
|
|
473
474
|
}
|
|
474
475
|
Object.assign(plan, attached.plan);
|
|
476
|
+
// #3284: stamp plan.acceptance from captured literals (stated or none_stated floor).
|
|
477
|
+
Object.assign(plan, stampAcceptanceFromLiteralCapture(plan));
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
// No body: still record none_stated acceptance so absence is a decision.
|
|
481
|
+
Object.assign(plan, stampAcceptanceFromLiteralCapture(plan));
|
|
475
482
|
}
|
|
476
483
|
const infoRootKey = options.infoRootKey ?? LEGACY_INFO_ROOT_KEY;
|
|
477
484
|
const infoVersion = options.infoVersion ?? EMITTED_VBRIEF_VERSION;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed plan.policy.acPassBanking (#3285).
|
|
3
|
+
*
|
|
4
|
+
* Surplus-threshold policy for post-AC-pass deepening: after the first
|
|
5
|
+
* stated-AC bank, agents may deepen only when remaining budget is at least
|
|
6
|
+
* this fraction of the hard max (default 0.2 = 20%).
|
|
7
|
+
*
|
|
8
|
+
* Composes #3266 bank-the-pass and product-first done-gate (#3284).
|
|
9
|
+
*/
|
|
10
|
+
/** Canonical dotted path for policy:show / PROJECT-DEFINITION. */
|
|
11
|
+
export declare const FIELD_AC_PASS_BANKING = "plan.policy.acPassBanking";
|
|
12
|
+
/** CLI alias for `task policy:show --field=acPassBanking`. */
|
|
13
|
+
export declare const FIELD_AC_PASS_BANKING_CLI_ALIAS = "acPassBanking";
|
|
14
|
+
/**
|
|
15
|
+
* Default surplus fraction of max turns/cost that must remain after bank
|
|
16
|
+
* before self-imposed deepening is allowed (#3285).
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_SURPLUS_THRESHOLD = 0.2;
|
|
19
|
+
/** Floor / ceiling for surplusThreshold (inclusive). */
|
|
20
|
+
export declare const SURPLUS_THRESHOLD_MIN = 0;
|
|
21
|
+
export declare const SURPLUS_THRESHOLD_MAX = 1;
|
|
22
|
+
/** Optional env override (fraction 0–1 or percent 0–100). */
|
|
23
|
+
export declare const ENV_SURPLUS_THRESHOLD = "DEFT_AC_PASS_SURPLUS_THRESHOLD";
|
|
24
|
+
export interface AcPassBankingConfig {
|
|
25
|
+
/**
|
|
26
|
+
* When false, surplus gate is inactive (unbounded / optional discipline only).
|
|
27
|
+
* Default true — the gate still only binds under a hard effort budget.
|
|
28
|
+
*/
|
|
29
|
+
readonly enabled: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Minimum remaining fraction of max turns/cost required to deepen after bank.
|
|
32
|
+
* Default {@link DEFAULT_SURPLUS_THRESHOLD} (0.2).
|
|
33
|
+
*/
|
|
34
|
+
readonly surplusThreshold: number;
|
|
35
|
+
}
|
|
36
|
+
export type AcPassBankingSource = "typed" | "env" | "default" | "default-on-error";
|
|
37
|
+
export interface AcPassBankingResolved extends AcPassBankingConfig {
|
|
38
|
+
readonly source: AcPassBankingSource;
|
|
39
|
+
readonly error: string | null;
|
|
40
|
+
}
|
|
41
|
+
/** Parse a 0–1 fraction or a 0–100 percent string/number into a fraction. */
|
|
42
|
+
export declare function parseSurplusThreshold(raw: unknown): number | null;
|
|
43
|
+
/** Validate a `plan.policy.acPassBanking` payload. */
|
|
44
|
+
export declare function validateAcPassBanking(value: unknown): string[];
|
|
45
|
+
/**
|
|
46
|
+
* Resolve surplus policy from typed plan.policy.acPassBanking, then env,
|
|
47
|
+
* then defaults (#3285).
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveAcPassBanking(projectRoot?: string | null, environ?: Readonly<Record<string, string | undefined>>): AcPassBankingResolved;
|
|
50
|
+
export interface AcPassBankingPolicyField {
|
|
51
|
+
readonly name: typeof FIELD_AC_PASS_BANKING;
|
|
52
|
+
readonly current: AcPassBankingConfig;
|
|
53
|
+
readonly default: AcPassBankingConfig;
|
|
54
|
+
readonly source: string;
|
|
55
|
+
}
|
|
56
|
+
/** Inspector row for `task policy:show --field=acPassBanking` (#3285). */
|
|
57
|
+
export declare function inspectAcPassBanking(_data: Record<string, unknown> | null, projectRoot?: string): AcPassBankingPolicyField;
|
|
58
|
+
//# sourceMappingURL=ac-pass-banking.d.ts.map
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed plan.policy.acPassBanking (#3285).
|
|
3
|
+
*
|
|
4
|
+
* Surplus-threshold policy for post-AC-pass deepening: after the first
|
|
5
|
+
* stated-AC bank, agents may deepen only when remaining budget is at least
|
|
6
|
+
* this fraction of the hard max (default 0.2 = 20%).
|
|
7
|
+
*
|
|
8
|
+
* Composes #3266 bank-the-pass and product-first done-gate (#3284).
|
|
9
|
+
*/
|
|
10
|
+
import { readPlanPolicy } from "./plan-extensions.js";
|
|
11
|
+
import { loadProjectDefinition } from "./resolve.js";
|
|
12
|
+
/** Canonical dotted path for policy:show / PROJECT-DEFINITION. */
|
|
13
|
+
export const FIELD_AC_PASS_BANKING = "plan.policy.acPassBanking";
|
|
14
|
+
/** CLI alias for `task policy:show --field=acPassBanking`. */
|
|
15
|
+
export const FIELD_AC_PASS_BANKING_CLI_ALIAS = "acPassBanking";
|
|
16
|
+
/**
|
|
17
|
+
* Default surplus fraction of max turns/cost that must remain after bank
|
|
18
|
+
* before self-imposed deepening is allowed (#3285).
|
|
19
|
+
*/
|
|
20
|
+
export const DEFAULT_SURPLUS_THRESHOLD = 0.2;
|
|
21
|
+
/** Floor / ceiling for surplusThreshold (inclusive). */
|
|
22
|
+
export const SURPLUS_THRESHOLD_MIN = 0;
|
|
23
|
+
export const SURPLUS_THRESHOLD_MAX = 1;
|
|
24
|
+
/** Optional env override (fraction 0–1 or percent 0–100). */
|
|
25
|
+
export const ENV_SURPLUS_THRESHOLD = "DEFT_AC_PASS_SURPLUS_THRESHOLD";
|
|
26
|
+
function defaultResolved(source, error = null, override) {
|
|
27
|
+
return {
|
|
28
|
+
enabled: override?.enabled ?? true,
|
|
29
|
+
surplusThreshold: override?.surplusThreshold ?? DEFAULT_SURPLUS_THRESHOLD,
|
|
30
|
+
source,
|
|
31
|
+
error,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Parse a 0–1 fraction or a 0–100 percent string/number into a fraction. */
|
|
35
|
+
export function parseSurplusThreshold(raw) {
|
|
36
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
37
|
+
if (raw >= 0 && raw <= 1)
|
|
38
|
+
return raw;
|
|
39
|
+
// Allow 20 meaning 20% when clearly a percent.
|
|
40
|
+
if (raw > 1 && raw <= 100)
|
|
41
|
+
return raw / 100;
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (typeof raw === "string") {
|
|
45
|
+
const text = raw.trim();
|
|
46
|
+
if (!text)
|
|
47
|
+
return null;
|
|
48
|
+
const percent = text.endsWith("%");
|
|
49
|
+
const n = Number(percent ? text.slice(0, -1).trim() : text);
|
|
50
|
+
if (!Number.isFinite(n))
|
|
51
|
+
return null;
|
|
52
|
+
if (percent) {
|
|
53
|
+
if (n < 0 || n > 100)
|
|
54
|
+
return null;
|
|
55
|
+
return n / 100;
|
|
56
|
+
}
|
|
57
|
+
if (n >= 0 && n <= 1)
|
|
58
|
+
return n;
|
|
59
|
+
if (n > 1 && n <= 100)
|
|
60
|
+
return n / 100;
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
/** Validate a `plan.policy.acPassBanking` payload. */
|
|
66
|
+
export function validateAcPassBanking(value) {
|
|
67
|
+
if (value === null || value === undefined) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
71
|
+
return [`${FIELD_AC_PASS_BANKING} must be an object; got ${typeof value}`];
|
|
72
|
+
}
|
|
73
|
+
const rec = value;
|
|
74
|
+
const errors = [];
|
|
75
|
+
if ("enabled" in rec && typeof rec.enabled !== "boolean") {
|
|
76
|
+
errors.push(`${FIELD_AC_PASS_BANKING}.enabled must be a boolean`);
|
|
77
|
+
}
|
|
78
|
+
if ("surplusThreshold" in rec) {
|
|
79
|
+
const parsed = parseSurplusThreshold(rec.surplusThreshold);
|
|
80
|
+
if (parsed === null) {
|
|
81
|
+
errors.push(`${FIELD_AC_PASS_BANKING}.surplusThreshold must be a fraction 0–1 ` +
|
|
82
|
+
`(or percent 0–100); got ${JSON.stringify(rec.surplusThreshold)}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return errors;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Resolve surplus policy from typed plan.policy.acPassBanking, then env,
|
|
89
|
+
* then defaults (#3285).
|
|
90
|
+
*/
|
|
91
|
+
export function resolveAcPassBanking(projectRoot, environ = process.env) {
|
|
92
|
+
if (projectRoot !== undefined && projectRoot !== null && projectRoot.length > 0) {
|
|
93
|
+
const [data, err] = loadProjectDefinition(projectRoot);
|
|
94
|
+
if (data !== null) {
|
|
95
|
+
const policyBlock = readPlanPolicy(data.plan);
|
|
96
|
+
if (typeof policyBlock === "object" &&
|
|
97
|
+
policyBlock !== null &&
|
|
98
|
+
!Array.isArray(policyBlock) &&
|
|
99
|
+
"acPassBanking" in policyBlock) {
|
|
100
|
+
const raw = policyBlock.acPassBanking;
|
|
101
|
+
const errors = validateAcPassBanking(raw);
|
|
102
|
+
if (errors.length > 0) {
|
|
103
|
+
return defaultResolved("default-on-error", errors[0] ?? "invalid acPassBanking");
|
|
104
|
+
}
|
|
105
|
+
if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
|
|
106
|
+
const rec = raw;
|
|
107
|
+
const enabled = typeof rec.enabled === "boolean" ? rec.enabled : true;
|
|
108
|
+
const threshold = "surplusThreshold" in rec
|
|
109
|
+
? (parseSurplusThreshold(rec.surplusThreshold) ?? DEFAULT_SURPLUS_THRESHOLD)
|
|
110
|
+
: DEFAULT_SURPLUS_THRESHOLD;
|
|
111
|
+
return {
|
|
112
|
+
enabled,
|
|
113
|
+
surplusThreshold: threshold,
|
|
114
|
+
source: "typed",
|
|
115
|
+
error: null,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else if (err !== null && err.length > 0) {
|
|
121
|
+
// Fall through to env/default; record nothing as fatal.
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const envRaw = environ[ENV_SURPLUS_THRESHOLD];
|
|
125
|
+
if (envRaw !== undefined && envRaw.trim() !== "") {
|
|
126
|
+
const parsed = parseSurplusThreshold(envRaw);
|
|
127
|
+
if (parsed !== null) {
|
|
128
|
+
return defaultResolved("env", null, { surplusThreshold: parsed });
|
|
129
|
+
}
|
|
130
|
+
return defaultResolved("default-on-error", `${ENV_SURPLUS_THRESHOLD} is not a valid fraction/percent: ${envRaw}`);
|
|
131
|
+
}
|
|
132
|
+
return defaultResolved("default");
|
|
133
|
+
}
|
|
134
|
+
/** Inspector row for `task policy:show --field=acPassBanking` (#3285). */
|
|
135
|
+
export function inspectAcPassBanking(_data, projectRoot) {
|
|
136
|
+
const resolved = resolveAcPassBanking(projectRoot);
|
|
137
|
+
return {
|
|
138
|
+
name: FIELD_AC_PASS_BANKING,
|
|
139
|
+
current: {
|
|
140
|
+
enabled: resolved.enabled,
|
|
141
|
+
surplusThreshold: resolved.surplusThreshold,
|
|
142
|
+
},
|
|
143
|
+
default: {
|
|
144
|
+
enabled: true,
|
|
145
|
+
surplusThreshold: DEFAULT_SURPLUS_THRESHOLD,
|
|
146
|
+
},
|
|
147
|
+
source: resolved.source,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=ac-pass-banking.js.map
|
|
@@ -286,4 +286,33 @@ export interface CeremonyDialAuditSnapshot {
|
|
|
286
286
|
export declare function readCeremonyDialAudit(projectRoot: string): CeremonyDialAuditSnapshot;
|
|
287
287
|
/** One-line operator summary for audit tooling / failed-task forensics (#3263). */
|
|
288
288
|
export declare function formatCeremonyDialAuditLine(audit: CeremonyDialAuditSnapshot): string;
|
|
289
|
+
/**
|
|
290
|
+
* Reified dial transition for run-summary telemetry (#3282).
|
|
291
|
+
*
|
|
292
|
+
* IMPLEMENTATION PREREQUISITE from the issue: dial transitions must be
|
|
293
|
+
* engine-managed events, not prose-only policy. This function is the CLI-facing
|
|
294
|
+
* transition hook (`policy:set-ceremony-dial` / dial escalate): it persists the
|
|
295
|
+
* override (when confirm) and always emits a `dial_transition` run-summary line
|
|
296
|
+
* when a depth change is applied.
|
|
297
|
+
*/
|
|
298
|
+
export interface EscalateCeremonyDialOptions {
|
|
299
|
+
readonly to: CeremonyDepth;
|
|
300
|
+
readonly reason: string;
|
|
301
|
+
readonly evidence?: string;
|
|
302
|
+
readonly sessionId?: string;
|
|
303
|
+
readonly confirm?: boolean;
|
|
304
|
+
readonly actor?: string;
|
|
305
|
+
readonly note?: string;
|
|
306
|
+
/** When false, skip run-summary emission (tests). Default true. */
|
|
307
|
+
readonly emitRunSummary?: boolean;
|
|
308
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
309
|
+
}
|
|
310
|
+
export interface EscalateCeremonyDialResult {
|
|
311
|
+
readonly exitCode: number;
|
|
312
|
+
readonly from: CeremonyDepth | null;
|
|
313
|
+
readonly to: CeremonyDepth;
|
|
314
|
+
readonly changed: boolean;
|
|
315
|
+
readonly lines: readonly string[];
|
|
316
|
+
}
|
|
317
|
+
export declare function escalateCeremonyDial(projectRoot: string, options: EscalateCeremonyDialOptions): EscalateCeremonyDialResult;
|
|
289
318
|
//# sourceMappingURL=ceremony-dial.d.ts.map
|