@deftai/directive-core 0.68.1 → 0.70.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/deposit/contain.d.ts +41 -0
- package/dist/deposit/contain.js +113 -0
- package/dist/deposit/copy-tree.js +8 -2
- package/dist/doctor/checks.d.ts +11 -0
- package/dist/doctor/checks.js +75 -2
- package/dist/doctor/constants.d.ts +9 -0
- package/dist/doctor/constants.js +11 -0
- package/dist/doctor/main.d.ts +47 -1
- package/dist/doctor/main.js +406 -3
- package/dist/doctor/manifest.d.ts +20 -0
- package/dist/doctor/manifest.js +22 -0
- package/dist/doctor/payload-staleness.d.ts +8 -0
- package/dist/doctor/payload-staleness.js +11 -8
- package/dist/doctor/types.d.ts +56 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/init-deposit/gitignore.d.ts +18 -0
- package/dist/init-deposit/gitignore.js +94 -15
- package/dist/init-deposit/headless-manifest.d.ts +87 -0
- package/dist/init-deposit/headless-manifest.js +261 -0
- package/dist/init-deposit/index.d.ts +3 -0
- package/dist/init-deposit/index.js +3 -0
- package/dist/init-deposit/init-deposit.js +6 -0
- package/dist/init-deposit/init-dispatch.d.ts +90 -0
- package/dist/init-deposit/init-dispatch.js +170 -0
- package/dist/init-deposit/refresh.d.ts +79 -2
- package/dist/init-deposit/refresh.js +182 -5
- package/dist/init-deposit/scaffold.d.ts +25 -0
- package/dist/init-deposit/scaffold.js +57 -0
- package/dist/init-deposit/untrack-core.d.ts +84 -0
- package/dist/init-deposit/untrack-core.js +150 -0
- package/dist/intake/issue-ingest.d.ts +11 -0
- package/dist/intake/issue-ingest.js +86 -11
- package/dist/policy/plan-extensions.d.ts +31 -0
- package/dist/policy/plan-extensions.js +45 -0
- package/dist/policy/wip.d.ts +2 -2
- package/dist/policy/wip.js +2 -2
- package/dist/resolution/classify.d.ts +41 -0
- package/dist/resolution/classify.js +138 -0
- package/dist/resolution/engine-ladder.d.ts +98 -0
- package/dist/resolution/engine-ladder.js +185 -0
- package/dist/resolution/index.d.ts +19 -0
- package/dist/resolution/index.js +19 -0
- package/dist/resolution/integrity.d.ts +48 -0
- package/dist/resolution/integrity.js +80 -0
- package/dist/resolution/package-manager.d.ts +77 -0
- package/dist/resolution/package-manager.js +103 -0
- package/dist/resolution/pin.d.ts +73 -0
- package/dist/resolution/pin.js +169 -0
- package/dist/resolution/plan.d.ts +66 -0
- package/dist/resolution/plan.js +219 -0
- package/dist/resolution/skew-policy.d.ts +46 -0
- package/dist/resolution/skew-policy.js +120 -0
- package/dist/session/session-start.d.ts +2 -0
- package/dist/session/session-start.js +28 -1
- package/dist/swarm/routing.js +10 -3
- package/dist/triage/bulk/index.d.ts +11 -2
- package/dist/triage/bulk/index.js +41 -4
- package/dist/triage/help/registry-data.d.ts +5 -5
- package/dist/triage/help/registry-data.js +18 -5
- package/dist/triage/scope/cli.d.ts +2 -1
- package/dist/triage/scope/cli.js +30 -6
- package/dist/triage/scope/mutations.d.ts +10 -0
- package/dist/triage/scope/mutations.js +22 -0
- package/dist/triage/welcome/constants.d.ts +1 -2
- package/dist/triage/welcome/constants.js +1 -2
- package/dist/triage/welcome/index.d.ts +1 -0
- package/dist/triage/welcome/index.js +1 -0
- package/dist/triage/welcome/onboard.d.ts +35 -0
- package/dist/triage/welcome/onboard.js +94 -0
- package/dist/umbrella-current-shape/index.d.ts +25 -1
- package/dist/umbrella-current-shape/index.js +84 -4
- package/dist/user-config/index.d.ts +2 -0
- package/dist/user-config/index.js +2 -0
- package/dist/user-config/resolve-user-md.d.ts +76 -0
- package/dist/user-config/resolve-user-md.js +120 -0
- package/dist/vbrief-build/project-definition-io.d.ts +6 -0
- package/dist/vbrief-build/project-definition-io.js +7 -2
- package/dist/vbrief-validate/precutover.js +7 -3
- package/dist/xbrief-migrate/constants.d.ts +10 -0
- package/dist/xbrief-migrate/constants.js +19 -0
- package/dist/xbrief-migrate/detect.d.ts +34 -0
- package/dist/xbrief-migrate/detect.js +33 -0
- package/dist/xbrief-migrate/fs-helpers.d.ts +13 -0
- package/dist/xbrief-migrate/fs-helpers.js +46 -1
- package/dist/xbrief-migrate/index.d.ts +4 -2
- package/dist/xbrief-migrate/index.js +4 -2
- package/dist/xbrief-migrate/migrate-project.d.ts +23 -1
- package/dist/xbrief-migrate/migrate-project.js +97 -8
- package/dist/xbrief-migrate/signpost.d.ts +7 -1
- package/dist/xbrief-migrate/signpost.js +18 -3
- package/package.json +7 -3
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three-band engine-vs-pin skew policy for the resolution spine (#2264, #2199).
|
|
3
|
+
*
|
|
4
|
+
* Content is always forward-migrated (`update`) before any gate runs; this
|
|
5
|
+
* policy governs whether a globally-reachable engine that differs from the pin
|
|
6
|
+
* may be used, and how loudly:
|
|
7
|
+
*
|
|
8
|
+
* - `engine == pin` -> proceed silently (trace only).
|
|
9
|
+
* - `engine > pin` within the skew window -> proceed, emit a loud delta, `update` first.
|
|
10
|
+
* - `engine > pin` beyond the window -> fail closed non-interactively (require
|
|
11
|
+
* `--accept-engine-jump`; prompt when interactive).
|
|
12
|
+
* `DEFT_ACCEPT_ENGINE_SKEW=1` is the CI escape.
|
|
13
|
+
* - `engine < pin` -> reject the global, fall through the ladder.
|
|
14
|
+
*/
|
|
15
|
+
import { compareSemver, parseSemver } from "./pin.js";
|
|
16
|
+
/** Default skew window pre-1.0, measured in minor versions. */
|
|
17
|
+
export const DEFAULT_ENGINE_SKEW_WINDOW = 3;
|
|
18
|
+
/** Environment variable that acts as the CI / non-interactive escape hatch. */
|
|
19
|
+
export const ACCEPT_ENGINE_SKEW_ENV = "DEFT_ACCEPT_ENGINE_SKEW";
|
|
20
|
+
function resolveWindow(opts) {
|
|
21
|
+
const raw = opts.engineSkewWindow;
|
|
22
|
+
if (typeof raw === "number" && Number.isInteger(raw) && raw >= 0)
|
|
23
|
+
return raw;
|
|
24
|
+
return DEFAULT_ENGINE_SKEW_WINDOW;
|
|
25
|
+
}
|
|
26
|
+
function escapeHatchActive(opts) {
|
|
27
|
+
if (opts.acceptEngineJump === true)
|
|
28
|
+
return true;
|
|
29
|
+
const env = opts.env ?? process.env;
|
|
30
|
+
return env[ACCEPT_ENGINE_SKEW_ENV] === "1";
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Classify the `engine > pin` skew band. Pre-1.0 (pin major 0) the window is
|
|
34
|
+
* measured in minors; post-1.0 the window collapses to "same major".
|
|
35
|
+
*/
|
|
36
|
+
function classifyAheadBand(engine, pin, window) {
|
|
37
|
+
const [engineMajor, engineMinor] = engine;
|
|
38
|
+
const [pinMajor, pinMinor] = pin;
|
|
39
|
+
if (pinMajor === 0) {
|
|
40
|
+
if (engineMajor > 0)
|
|
41
|
+
return "beyond-window";
|
|
42
|
+
return engineMinor - pinMinor <= window ? "within-window" : "beyond-window";
|
|
43
|
+
}
|
|
44
|
+
return engineMajor === pinMajor ? "within-window" : "beyond-window";
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Evaluate the three-band skew policy for a reachable engine against the pin.
|
|
48
|
+
* Unparseable versions fail closed (a version we cannot order is not safe to run).
|
|
49
|
+
*/
|
|
50
|
+
export function evaluateSkew(engineVersion, pinVersion, opts = {}) {
|
|
51
|
+
const engine = parseSemver(engineVersion);
|
|
52
|
+
const pin = parseSemver(pinVersion);
|
|
53
|
+
if (engine === null || pin === null) {
|
|
54
|
+
return {
|
|
55
|
+
band: "unknown",
|
|
56
|
+
decision: "fail-closed",
|
|
57
|
+
message: `cannot order engine (${engineVersion ?? "unknown"}) against pin (${pinVersion ?? "unknown"}); refusing to run an unorderable engine`,
|
|
58
|
+
requiresUpdateFirst: false,
|
|
59
|
+
escapeHatchUsed: false,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const cmp = compareSemver(engineVersion, pinVersion);
|
|
63
|
+
if (cmp === 0) {
|
|
64
|
+
return {
|
|
65
|
+
band: "match",
|
|
66
|
+
decision: "proceed-silent",
|
|
67
|
+
message: null,
|
|
68
|
+
requiresUpdateFirst: false,
|
|
69
|
+
escapeHatchUsed: false,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (cmp === -1) {
|
|
73
|
+
return {
|
|
74
|
+
band: "engine-behind",
|
|
75
|
+
decision: "reject-global",
|
|
76
|
+
message: `engine ${engineVersion} is behind pin ${pinVersion}; rejecting global engine and falling through the ladder`,
|
|
77
|
+
requiresUpdateFirst: false,
|
|
78
|
+
escapeHatchUsed: false,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// engine > pin
|
|
82
|
+
const window = resolveWindow(opts);
|
|
83
|
+
const band = classifyAheadBand(engine, pin, window);
|
|
84
|
+
if (band === "within-window") {
|
|
85
|
+
return {
|
|
86
|
+
band,
|
|
87
|
+
decision: "proceed-loud-update",
|
|
88
|
+
message: `engine ${engineVersion} is ahead of pin ${pinVersion} within the skew window; proceeding after content update`,
|
|
89
|
+
requiresUpdateFirst: true,
|
|
90
|
+
escapeHatchUsed: false,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// beyond-window
|
|
94
|
+
if (escapeHatchActive(opts)) {
|
|
95
|
+
return {
|
|
96
|
+
band,
|
|
97
|
+
decision: "proceed-loud-update",
|
|
98
|
+
message: `engine ${engineVersion} is a large jump ahead of pin ${pinVersion}; accepted via escape hatch (--accept-engine-jump / ${ACCEPT_ENGINE_SKEW_ENV}=1)`,
|
|
99
|
+
requiresUpdateFirst: true,
|
|
100
|
+
escapeHatchUsed: true,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (opts.interactive === true) {
|
|
104
|
+
return {
|
|
105
|
+
band,
|
|
106
|
+
decision: "prompt",
|
|
107
|
+
message: `engine ${engineVersion} is a large jump ahead of pin ${pinVersion}; prompt the operator to confirm (or pass --accept-engine-jump)`,
|
|
108
|
+
requiresUpdateFirst: true,
|
|
109
|
+
escapeHatchUsed: false,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
band,
|
|
114
|
+
decision: "fail-closed",
|
|
115
|
+
message: `engine ${engineVersion} is a large jump ahead of pin ${pinVersion}; failing closed. Re-run with --accept-engine-jump or ${ACCEPT_ENGINE_SKEW_ENV}=1`,
|
|
116
|
+
requiresUpdateFirst: false,
|
|
117
|
+
escapeHatchUsed: false,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=skew-policy.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ResolveUserMdResult } from "../user-config/resolve-user-md.js";
|
|
1
2
|
import type { GitRunner } from "./git.js";
|
|
2
3
|
import { ritualStatePath } from "./ritual-sentinel.js";
|
|
3
4
|
export declare const QUICK_STEPS: readonly ["alignment", "branch_policy", "triage_welcome"];
|
|
@@ -30,6 +31,7 @@ export interface SessionStartOptions {
|
|
|
30
31
|
readonly verifyTools?: (output: (line: string) => void) => {
|
|
31
32
|
exitCode: number;
|
|
32
33
|
};
|
|
34
|
+
readonly resolveUserMd?: (projectRoot: string) => ResolveUserMdResult;
|
|
33
35
|
}
|
|
34
36
|
export declare function parseDeferrals(rawValues: readonly string[]): {
|
|
35
37
|
deferrals: Record<string, string>;
|
|
@@ -4,6 +4,7 @@ import { MIGRATE_COMPLETION_NUDGE, shouldEmitMigrateNudge } from "../init-deposi
|
|
|
4
4
|
import { disclosureLine } from "../policy/disclosure.js";
|
|
5
5
|
import { resolvePolicy } from "../policy/resolve.js";
|
|
6
6
|
import { runDefaultMode } from "../triage/welcome/default-mode.js";
|
|
7
|
+
import { resolveUserMdPath } from "../user-config/resolve-user-md.js";
|
|
7
8
|
import { verifyRequiredTools } from "../verify-env/verify-tools.js";
|
|
8
9
|
import { defaultGitRunner, gitHead, worktreePath } from "./git.js";
|
|
9
10
|
import { newRitualStatePayload, ritualStatePath, ritualStep, writeRitualState, } from "./ritual-sentinel.js";
|
|
@@ -194,10 +195,30 @@ export function runSessionStart(projectRoot, options = {}) {
|
|
|
194
195
|
const quickSteps = recordDeferredSteps(QUICK_STEPS, deferrals, instant);
|
|
195
196
|
const gatedSteps = recordDeferredSteps(GATED_STEPS, deferrals, instant);
|
|
196
197
|
const lines = [];
|
|
198
|
+
// Resolve USER.md via the shared first-hit-wins resolver so the alignment
|
|
199
|
+
// step finds preferences automatically in mismatched / headless sandboxes
|
|
200
|
+
// with zero manual DEFT_USER_PATH (#2271 / #2124). Never throws: an absent
|
|
201
|
+
// USER.md degrades to a clear diagnostic below.
|
|
202
|
+
const resolveUserMd = options.resolveUserMd ?? ((root) => resolveUserMdPath({ projectRoot: root }));
|
|
203
|
+
const userMd = resolveUserMd(projectRoot);
|
|
197
204
|
if (!quickSteps.alignment) {
|
|
198
205
|
const message = "Deft Directive active -- AGENTS.md loaded.";
|
|
199
|
-
|
|
206
|
+
// Sanitize newlines on the data-derived path/diagnostic before they land in
|
|
207
|
+
// the ritual-step message / terminal output (matches doctor's CWE-116
|
|
208
|
+
// handling); DEFT_USER_PATH is only trimmed, so an embedded newline could
|
|
209
|
+
// otherwise survive into multi-line output.
|
|
210
|
+
const safePath = userMd.path.replace(/\r?\n/g, " ");
|
|
211
|
+
const safeDiagnostic = userMd.diagnostic.replace(/\r?\n/g, " ");
|
|
212
|
+
const userMdLine = userMd.found
|
|
213
|
+
? `USER.md resolved (${userMd.rung}): ${safePath}`
|
|
214
|
+
: safeDiagnostic;
|
|
215
|
+
quickSteps.alignment = ritualStep({
|
|
216
|
+
ok: true,
|
|
217
|
+
ts: instant,
|
|
218
|
+
message: `${message} ${userMdLine}`,
|
|
219
|
+
});
|
|
200
220
|
lines.push(message);
|
|
221
|
+
lines.push(userMdLine);
|
|
201
222
|
}
|
|
202
223
|
if (!quickSteps.branch_policy) {
|
|
203
224
|
const result = resolvePolicy(projectRoot);
|
|
@@ -287,6 +308,12 @@ export function runSessionStart(projectRoot, options = {}) {
|
|
|
287
308
|
state_path: statePath,
|
|
288
309
|
quick_steps: quickSteps,
|
|
289
310
|
gated_steps: gatedSteps,
|
|
311
|
+
user_md: {
|
|
312
|
+
path: userMd.path,
|
|
313
|
+
rung: userMd.rung,
|
|
314
|
+
found: userMd.found,
|
|
315
|
+
diagnostic: userMd.diagnostic,
|
|
316
|
+
},
|
|
290
317
|
message: code === 0 ? "session ritual recorded" : "session ritual failed",
|
|
291
318
|
};
|
|
292
319
|
return { code, payload: resultPayload, lines };
|
package/dist/swarm/routing.js
CHANGED
|
@@ -186,7 +186,9 @@ export function resolveDispatchProvider(environ = process.env) {
|
|
|
186
186
|
* Keys that would mutate the prototype chain rather than set an own property
|
|
187
187
|
* if used as a computed object key. Rejected for provider/role names so a
|
|
188
188
|
* malicious routing input cannot pollute `Object.prototype` (CodeQL
|
|
189
|
-
* js/prototype-polluting-assignment).
|
|
189
|
+
* js/prototype-polluting-assignment). This validation guard produces the
|
|
190
|
+
* caller-facing error; the null-prototype write targets in
|
|
191
|
+
* `writeModelDecision` are the structural backstop CodeQL recognizes.
|
|
190
192
|
*/
|
|
191
193
|
const FORBIDDEN_ROUTING_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
192
194
|
function assertSafeRoutingKey(kind, key) {
|
|
@@ -203,9 +205,14 @@ export function writeModelDecision(path, provider, role, decision) {
|
|
|
203
205
|
assertSafeRoutingKey("provider", provider);
|
|
204
206
|
assertSafeRoutingKey("role", role);
|
|
205
207
|
const { data } = loadRoutingFile(path);
|
|
206
|
-
|
|
208
|
+
// Null-prototype write targets so a computed provider/role key can only ever
|
|
209
|
+
// set an own property and can never reach `Object.prototype`, even if the
|
|
210
|
+
// validation guard above regresses. CodeQL's js/prototype-polluting-assignment
|
|
211
|
+
// barrier does not track the interprocedural `assertSafeRoutingKey` guard, so
|
|
212
|
+
// this structural sink is what closes alert #52.
|
|
213
|
+
const file = Object.assign(Object.create(null), data ?? {});
|
|
207
214
|
const existing = providerBlockOf(file, provider);
|
|
208
|
-
const block = existing ?? {};
|
|
215
|
+
const block = Object.assign(Object.create(null), existing ?? {});
|
|
209
216
|
block[role] = {
|
|
210
217
|
model: decision.model,
|
|
211
218
|
mode: decision.mode ??
|
|
@@ -88,12 +88,21 @@ export declare function excludeLogged(candidates: Iterable<IssuePayload>, option
|
|
|
88
88
|
export declare function bulkAction(actionKey: string, repo: string, options?: BulkActionOptions): number;
|
|
89
89
|
export declare function createFilesystemCacheModule(): CacheModule;
|
|
90
90
|
export declare function createFilesystemCandidatesLogModule(logPath?: string): CandidatesLogModule;
|
|
91
|
+
/**
|
|
92
|
+
* Native TypeScript bulk actions module (#2279).
|
|
93
|
+
*
|
|
94
|
+
* The bulk path defaults to this factory instead of {@link createPythonActionsModule}
|
|
95
|
+
* so `triage:bulk-*` never spawns a project-local `scripts/triage_actions.py`
|
|
96
|
+
* (an arbitrary-code-execution trust boundary a malicious checkout could plant).
|
|
97
|
+
* Each verb delegates to the already-native per-issue triage actions
|
|
98
|
+
* (`@deftai/directive-core/triage/actions`, #1725) bound to `createDefaultDeps(projectRoot)`.
|
|
99
|
+
*/
|
|
100
|
+
export declare function createNativeActionsModule(projectRoot: string): TriageActionsModule;
|
|
91
101
|
export declare function createPythonActionsModule(scriptsDir: string): TriageActionsModule;
|
|
92
102
|
export interface DefaultBulkDepsOptions {
|
|
93
103
|
readonly cacheRoot?: string;
|
|
94
104
|
readonly candidatesLogPath?: string;
|
|
95
|
-
readonly
|
|
96
|
-
readonly deftRoot?: string;
|
|
105
|
+
readonly projectRoot?: string;
|
|
97
106
|
}
|
|
98
107
|
export declare function bulkActionWithDefaults(actionKey: string, repo: string, options?: BulkActionOptions & DefaultBulkDepsOptions): number;
|
|
99
108
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -2,6 +2,7 @@ import { spawnSync } from "node:child_process";
|
|
|
2
2
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { resolveEvalPath } from "../../layout/resolve.js";
|
|
5
|
+
import { createDefaultDeps, accept as nativeAccept, deferAction as nativeDefer, needsAc as nativeNeedsAc, reject as nativeReject, } from "../actions/index.js";
|
|
5
6
|
export const ACTION_FN_NAMES = {
|
|
6
7
|
accept: "accept",
|
|
7
8
|
reject: "reject",
|
|
@@ -402,6 +403,40 @@ export function createFilesystemCandidatesLogModule(logPath = resolveEvalPath(pr
|
|
|
402
403
|
},
|
|
403
404
|
};
|
|
404
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Native TypeScript bulk actions module (#2279).
|
|
408
|
+
*
|
|
409
|
+
* The bulk path defaults to this factory instead of {@link createPythonActionsModule}
|
|
410
|
+
* so `triage:bulk-*` never spawns a project-local `scripts/triage_actions.py`
|
|
411
|
+
* (an arbitrary-code-execution trust boundary a malicious checkout could plant).
|
|
412
|
+
* Each verb delegates to the already-native per-issue triage actions
|
|
413
|
+
* (`@deftai/directive-core/triage/actions`, #1725) bound to `createDefaultDeps(projectRoot)`.
|
|
414
|
+
*/
|
|
415
|
+
export function createNativeActionsModule(projectRoot) {
|
|
416
|
+
const deps = createDefaultDeps(projectRoot);
|
|
417
|
+
return {
|
|
418
|
+
accept(n, repo) {
|
|
419
|
+
nativeAccept(n, repo, deps, { projectRoot });
|
|
420
|
+
},
|
|
421
|
+
reject(n, repo, ...args) {
|
|
422
|
+
let reason = "";
|
|
423
|
+
const first = args[0];
|
|
424
|
+
if (typeof first === "object" && first !== null && "reason" in first) {
|
|
425
|
+
reason = String(first.reason);
|
|
426
|
+
}
|
|
427
|
+
else if (typeof first === "string") {
|
|
428
|
+
reason = first;
|
|
429
|
+
}
|
|
430
|
+
nativeReject(n, repo, reason, deps, { projectRoot });
|
|
431
|
+
},
|
|
432
|
+
defer(n, repo) {
|
|
433
|
+
nativeDefer(n, repo, "bulk defer", deps, { projectRoot });
|
|
434
|
+
},
|
|
435
|
+
needs_ac(n, repo) {
|
|
436
|
+
nativeNeedsAc(n, repo, deps, { projectRoot });
|
|
437
|
+
},
|
|
438
|
+
};
|
|
439
|
+
}
|
|
405
440
|
export function createPythonActionsModule(scriptsDir) {
|
|
406
441
|
const runAction = (cmd, issueNumber, repo, extra = []) => {
|
|
407
442
|
const result = spawnSync("uv", [
|
|
@@ -442,14 +477,16 @@ export function createPythonActionsModule(scriptsDir) {
|
|
|
442
477
|
};
|
|
443
478
|
}
|
|
444
479
|
export function bulkActionWithDefaults(actionKey, repo, options = {}) {
|
|
445
|
-
|
|
446
|
-
|
|
480
|
+
// #2279: the bulk path no longer resolves a `scripts/` dir from DEFT_ROOT /
|
|
481
|
+
// the project cwd. It defaults to the native TypeScript actions module so a
|
|
482
|
+
// malicious project-local `scripts/triage_actions.py` can never be executed.
|
|
483
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
447
484
|
return bulkAction(actionKey, repo, {
|
|
448
485
|
...options,
|
|
449
|
-
cacheRoot: options.cacheRoot ?? join(
|
|
486
|
+
cacheRoot: options.cacheRoot ?? join(projectRoot, ".deft-cache"),
|
|
450
487
|
cacheModule: options.cacheModule ?? createFilesystemCacheModule(),
|
|
451
488
|
candidatesLogModule: options.candidatesLogModule ?? createFilesystemCandidatesLogModule(options.candidatesLogPath),
|
|
452
|
-
actionsModule: options.actionsModule ??
|
|
489
|
+
actionsModule: options.actionsModule ?? createNativeActionsModule(projectRoot),
|
|
453
490
|
});
|
|
454
491
|
}
|
|
455
492
|
//# sourceMappingURL=index.js.map
|
|
@@ -191,11 +191,11 @@ export declare const registryData: {
|
|
|
191
191
|
readonly "task triage:welcome": {
|
|
192
192
|
readonly name: "task triage:welcome";
|
|
193
193
|
readonly summary: "Single-entry-point upgrade ritual";
|
|
194
|
-
readonly refs: "(N3 / #1143)";
|
|
195
|
-
readonly description: "6-phase onboarding ritual: detect prior state, prompt for subscription scope, run triage:bootstrap, prompt for wipCap, offer WIP relief, print triage:summary. Idempotent on re-run; safe entrypoint for fresh consumers.";
|
|
196
|
-
readonly usage: "task triage:welcome [-- --no-subprocess]";
|
|
197
|
-
readonly flags: readonly [readonly ["--no-subprocess", "(off)", "Dry-mode: don't shell out to sibling tasks."]];
|
|
198
|
-
readonly examples: readonly ["task triage:welcome"];
|
|
194
|
+
readonly refs: "(N3 / #1143, #2295)";
|
|
195
|
+
readonly description: "6-phase onboarding ritual: detect prior state, prompt for subscription scope, run triage:bootstrap, prompt for wipCap, offer WIP relief, print triage:summary. Idempotent on re-run; safe entrypoint for fresh consumers. Pass --onboard for the non-interactive path that applies a triage-scope preset (and optional --wip-cap) without prompting -- the form agents/CI use.";
|
|
196
|
+
readonly usage: "task triage:welcome [-- --onboard [--preset small|mid|mega] [--wip-cap N]] [--no-subprocess]";
|
|
197
|
+
readonly flags: readonly [readonly ["--onboard", "(off)", "Non-interactive onboarding: apply a triage-scope preset (and optional WIP cap) without prompting."], readonly ["--preset small|mid|mega", "small", "Subscription-scope preset applied by --onboard."], readonly ["--wip-cap N", "(policy default)", "Persist an explicit in-flight scope cap during --onboard (positive integer)."], readonly ["--no-subprocess", "(off)", "Dry-mode: don't shell out to sibling tasks."]];
|
|
198
|
+
readonly examples: readonly ["task triage:welcome", "task triage:welcome -- --onboard --preset small"];
|
|
199
199
|
readonly see_also: readonly ["task triage:bootstrap", "task triage:summary", "#1119 / N3"];
|
|
200
200
|
readonly placeholder: false;
|
|
201
201
|
};
|
|
@@ -296,11 +296,24 @@ export const registryData = {
|
|
|
296
296
|
"task triage:welcome": {
|
|
297
297
|
name: "task triage:welcome",
|
|
298
298
|
summary: "Single-entry-point upgrade ritual",
|
|
299
|
-
refs: "(N3 / #1143)",
|
|
300
|
-
description: "6-phase onboarding ritual: detect prior state, prompt for subscription scope, run triage:bootstrap, prompt for wipCap, offer WIP relief, print triage:summary. Idempotent on re-run; safe entrypoint for fresh consumers.",
|
|
301
|
-
usage: "task triage:welcome [-- --no-subprocess]",
|
|
302
|
-
flags: [
|
|
303
|
-
|
|
299
|
+
refs: "(N3 / #1143, #2295)",
|
|
300
|
+
description: "6-phase onboarding ritual: detect prior state, prompt for subscription scope, run triage:bootstrap, prompt for wipCap, offer WIP relief, print triage:summary. Idempotent on re-run; safe entrypoint for fresh consumers. Pass --onboard for the non-interactive path that applies a triage-scope preset (and optional --wip-cap) without prompting -- the form agents/CI use.",
|
|
301
|
+
usage: "task triage:welcome [-- --onboard [--preset small|mid|mega] [--wip-cap N]] [--no-subprocess]",
|
|
302
|
+
flags: [
|
|
303
|
+
[
|
|
304
|
+
"--onboard",
|
|
305
|
+
"(off)",
|
|
306
|
+
"Non-interactive onboarding: apply a triage-scope preset (and optional WIP cap) without prompting.",
|
|
307
|
+
],
|
|
308
|
+
["--preset small|mid|mega", "small", "Subscription-scope preset applied by --onboard."],
|
|
309
|
+
[
|
|
310
|
+
"--wip-cap N",
|
|
311
|
+
"(policy default)",
|
|
312
|
+
"Persist an explicit in-flight scope cap during --onboard (positive integer).",
|
|
313
|
+
],
|
|
314
|
+
["--no-subprocess", "(off)", "Dry-mode: don't shell out to sibling tasks."],
|
|
315
|
+
],
|
|
316
|
+
examples: ["task triage:welcome", "task triage:welcome -- --onboard --preset small"],
|
|
304
317
|
see_also: ["task triage:bootstrap", "task triage:summary", "#1119 / N3"],
|
|
305
318
|
placeholder: false,
|
|
306
319
|
},
|
|
@@ -6,13 +6,14 @@ export interface ParsedCliArgs {
|
|
|
6
6
|
addLabel: string | undefined;
|
|
7
7
|
addMilestone: string | undefined;
|
|
8
8
|
ignoreLabel: string | undefined;
|
|
9
|
+
setPreset: string | undefined;
|
|
9
10
|
diffFromUpstream: boolean;
|
|
10
11
|
source: string;
|
|
11
12
|
cacheRoot: string | undefined;
|
|
12
13
|
count: number | undefined;
|
|
13
14
|
}
|
|
14
15
|
export declare function parseCliArgs(argv: string[]): ParsedCliArgs;
|
|
15
|
-
export declare const CLI_HELP = "usage: triage_scope.py [-h] [--project-root PROJECT_ROOT] [--list]\n [--refresh-denominator] [--repo REPO]\n [--add-label ADD_LABEL] [--add-milestone ADD_MILESTONE]\n [--ignore-label IGNORE_LABEL] [--diff-from-upstream]\n [--source SOURCE] [--cache-root CACHE_ROOT]\n [--count COUNT]\n\nInspect, mutate, and diff the typed plan.policy.triageScope[] subscription +\nplan.policy.triageScopeIgnores[] (#1131 / D12, #1133 / D14, #1182 / D14c).\nRead paths never trigger a recompute; use --refresh-denominator to update the\ncoverage cache. Mutation flags --add-label / --add-milestone / --ignore-label
|
|
16
|
+
export declare const CLI_HELP = "usage: triage_scope.py [-h] [--project-root PROJECT_ROOT] [--list]\n [--refresh-denominator] [--repo REPO]\n [--add-label ADD_LABEL] [--add-milestone ADD_MILESTONE]\n [--ignore-label IGNORE_LABEL] [--set-preset PRESET]\n [--diff-from-upstream]\n [--source SOURCE] [--cache-root CACHE_ROOT]\n [--count COUNT]\n\nInspect, mutate, and diff the typed plan.policy.triageScope[] subscription +\nplan.policy.triageScopeIgnores[] (#1131 / D12, #1133 / D14, #1182 / D14c).\nRead paths never trigger a recompute; use --refresh-denominator to update the\ncoverage cache. Mutation flags --add-label / --add-milestone / --ignore-label /\n--set-preset are idempotent and atomic; every mutation appends a\nsubscription-change audit entry to vbrief/.eval/subscription-history.jsonl.\n--set-preset small|mid|mega overwrites plan.policy.triageScope[] with a named\nsubscription preset via the same writer that backs triage:welcome --onboard (#2301).\n";
|
|
16
17
|
/** Run triage:scope CLI; returns exit code and captured output for parity. */
|
|
17
18
|
export declare function runCliCapture(argv: string[]): {
|
|
18
19
|
code: number;
|
package/dist/triage/scope/cli.js
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { coveragePath, writeCoverageDenominator } from "./coverage.js";
|
|
5
|
-
import { addLabelToIgnores, addLabelToScope, addMilestoneToScope, computeDiffFromUpstream, fetchUpstreamLabelsAndMilestones, renderDiffReport, } from "./mutations.js";
|
|
5
|
+
import { addLabelToIgnores, addLabelToScope, addMilestoneToScope, computeDiffFromUpstream, fetchUpstreamLabelsAndMilestones, renderDiffReport, setScopePreset, } from "./mutations.js";
|
|
6
6
|
import { subscriptionHash } from "./normalize.js";
|
|
7
7
|
import { pyListRepr } from "./python-repr.js";
|
|
8
8
|
import { renderIgnores, renderList } from "./renderers.js";
|
|
@@ -17,6 +17,7 @@ export function parseCliArgs(argv) {
|
|
|
17
17
|
addLabel: undefined,
|
|
18
18
|
addMilestone: undefined,
|
|
19
19
|
ignoreLabel: undefined,
|
|
20
|
+
setPreset: undefined,
|
|
20
21
|
diffFromUpstream: false,
|
|
21
22
|
source: "github-issue",
|
|
22
23
|
cacheRoot: undefined,
|
|
@@ -60,6 +61,12 @@ export function parseCliArgs(argv) {
|
|
|
60
61
|
}
|
|
61
62
|
else if (arg?.startsWith("--ignore-label="))
|
|
62
63
|
parsed.ignoreLabel = arg.slice("--ignore-label=".length);
|
|
64
|
+
else if (arg === "--set-preset") {
|
|
65
|
+
parsed.setPreset = argv[i + 1];
|
|
66
|
+
i += 1;
|
|
67
|
+
}
|
|
68
|
+
else if (arg?.startsWith("--set-preset="))
|
|
69
|
+
parsed.setPreset = arg.slice("--set-preset=".length);
|
|
63
70
|
else if (arg === "--source") {
|
|
64
71
|
parsed.source = argv[i + 1] ?? "github-issue";
|
|
65
72
|
i += 1;
|
|
@@ -86,16 +93,19 @@ export function parseCliArgs(argv) {
|
|
|
86
93
|
export const CLI_HELP = `usage: triage_scope.py [-h] [--project-root PROJECT_ROOT] [--list]
|
|
87
94
|
[--refresh-denominator] [--repo REPO]
|
|
88
95
|
[--add-label ADD_LABEL] [--add-milestone ADD_MILESTONE]
|
|
89
|
-
[--ignore-label IGNORE_LABEL] [--
|
|
96
|
+
[--ignore-label IGNORE_LABEL] [--set-preset PRESET]
|
|
97
|
+
[--diff-from-upstream]
|
|
90
98
|
[--source SOURCE] [--cache-root CACHE_ROOT]
|
|
91
99
|
[--count COUNT]
|
|
92
100
|
|
|
93
101
|
Inspect, mutate, and diff the typed plan.policy.triageScope[] subscription +
|
|
94
102
|
plan.policy.triageScopeIgnores[] (#1131 / D12, #1133 / D14, #1182 / D14c).
|
|
95
103
|
Read paths never trigger a recompute; use --refresh-denominator to update the
|
|
96
|
-
coverage cache. Mutation flags --add-label / --add-milestone / --ignore-label
|
|
97
|
-
are idempotent and atomic; every mutation appends a
|
|
98
|
-
entry to vbrief/.eval/subscription-history.jsonl.
|
|
104
|
+
coverage cache. Mutation flags --add-label / --add-milestone / --ignore-label /
|
|
105
|
+
--set-preset are idempotent and atomic; every mutation appends a
|
|
106
|
+
subscription-change audit entry to vbrief/.eval/subscription-history.jsonl.
|
|
107
|
+
--set-preset small|mid|mega overwrites plan.policy.triageScope[] with a named
|
|
108
|
+
subscription preset via the same writer that backs triage:welcome --onboard (#2301).
|
|
99
109
|
`;
|
|
100
110
|
function handleMutation(projectRoot, args) {
|
|
101
111
|
const out = { stdout: [], stderr: [] };
|
|
@@ -115,6 +125,10 @@ function handleMutation(projectRoot, args) {
|
|
|
115
125
|
[changed, message] = addLabelToIgnores(projectRoot, args.ignoreLabel);
|
|
116
126
|
verb = "ignore-label";
|
|
117
127
|
}
|
|
128
|
+
else if (args.setPreset !== undefined) {
|
|
129
|
+
[changed, message] = setScopePreset(projectRoot, args.setPreset);
|
|
130
|
+
verb = "set-preset";
|
|
131
|
+
}
|
|
118
132
|
else {
|
|
119
133
|
throw new Error("internal: mutation flag set but no handler matched");
|
|
120
134
|
}
|
|
@@ -148,12 +162,13 @@ export function runCliCapture(argv) {
|
|
|
148
162
|
args.addLabel !== undefined ? "--add-label" : null,
|
|
149
163
|
args.addMilestone !== undefined ? "--add-milestone" : null,
|
|
150
164
|
args.ignoreLabel !== undefined ? "--ignore-label" : null,
|
|
165
|
+
args.setPreset !== undefined ? "--set-preset" : null,
|
|
151
166
|
].filter((f) => f !== null);
|
|
152
167
|
if (mutationFlags.length > 1) {
|
|
153
168
|
return {
|
|
154
169
|
code: 2,
|
|
155
170
|
stdout: "",
|
|
156
|
-
stderr: "triage:scope: --add-label / --add-milestone / --ignore-label " +
|
|
171
|
+
stderr: "triage:scope: --add-label / --add-milestone / --ignore-label / --set-preset " +
|
|
157
172
|
`are mutually exclusive (got ${pyListRepr(mutationFlags)}).\n`,
|
|
158
173
|
};
|
|
159
174
|
}
|
|
@@ -171,6 +186,15 @@ export function runCliCapture(argv) {
|
|
|
171
186
|
if (mutation.code !== 0) {
|
|
172
187
|
return { code: mutation.code, stdout: stdout.join(""), stderr: stderr.join("") };
|
|
173
188
|
}
|
|
189
|
+
// A preset write comes from the trusted SUBSCRIPTION_PRESETS constant (the
|
|
190
|
+
// same source the onboard path writes). The `mega` preset intentionally
|
|
191
|
+
// ships an `explicit-watch` scaffold with an empty `issues` list for the
|
|
192
|
+
// operator to fill in, which the strict hand-edit validator below flags.
|
|
193
|
+
// Bypass that re-validation for a preset write so `--set-preset` reports the
|
|
194
|
+
// successful, persisted mutation instead of a spurious exit 1 (#2301).
|
|
195
|
+
if (args.setPreset !== undefined) {
|
|
196
|
+
return { code: 0, stdout: stdout.join(""), stderr: stderr.join("") };
|
|
197
|
+
}
|
|
174
198
|
}
|
|
175
199
|
const data = loadProjectDefinition(projectRoot);
|
|
176
200
|
const rules = resolveScopeRules(projectRoot, data);
|
|
@@ -18,4 +18,14 @@ export declare function fetchUpstreamLabelsAndMilestones(repo: string, binary?:
|
|
|
18
18
|
export declare function addLabelToScope(projectRoot: string, label: string, actor?: string | null): [boolean, string];
|
|
19
19
|
export declare function addMilestoneToScope(projectRoot: string, milestone: string, actor?: string | null): [boolean, string];
|
|
20
20
|
export declare function addLabelToIgnores(projectRoot: string, label: string): [boolean, string];
|
|
21
|
+
/** Valid subscription preset keys for `triage:scope --set-preset` (#2301). */
|
|
22
|
+
export declare function scopePresetKeys(): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Overwrite plan.policy.triageScope with a named subscription preset (#2301).
|
|
25
|
+
* Reuses the shared `subscriptionPreset` + `writeTriageScope` helper that backs
|
|
26
|
+
* `triage:welcome --onboard`, so the write path (namespaced key, legacy-key
|
|
27
|
+
* migration, audit trail, mutation lock) stays identical across surfaces rather
|
|
28
|
+
* than being duplicated here.
|
|
29
|
+
*/
|
|
30
|
+
export declare function setScopePreset(projectRoot: string, presetKey: string): [boolean, string];
|
|
21
31
|
//# sourceMappingURL=mutations.d.ts.map
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { SUBPROCESS_MAX_BUFFER } from "../../subprocess/max-buffer.js";
|
|
3
|
+
import { SUBSCRIPTION_PRESETS } from "../welcome/constants.js";
|
|
4
|
+
import { subscriptionPreset, writeTriageScope } from "../welcome/writers.js";
|
|
3
5
|
import { collectMilestoneSubscribedNames, rulesRequestIsOpen } from "./milestone.js";
|
|
4
6
|
import { addIgnore, subscribe } from "./mutations-core.js";
|
|
5
7
|
import { resolveScopeIgnores, resolveScopeRules } from "./resolve.js";
|
|
@@ -200,4 +202,24 @@ export function addLabelToIgnores(projectRoot, label) {
|
|
|
200
202
|
throw new Error(`label must be a non-empty string; got ${JSON.stringify(label)}`);
|
|
201
203
|
return addIgnore(projectRoot, label);
|
|
202
204
|
}
|
|
205
|
+
/** Valid subscription preset keys for `triage:scope --set-preset` (#2301). */
|
|
206
|
+
export function scopePresetKeys() {
|
|
207
|
+
return Object.keys(SUBSCRIPTION_PRESETS);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Overwrite plan.policy.triageScope with a named subscription preset (#2301).
|
|
211
|
+
* Reuses the shared `subscriptionPreset` + `writeTriageScope` helper that backs
|
|
212
|
+
* `triage:welcome --onboard`, so the write path (namespaced key, legacy-key
|
|
213
|
+
* migration, audit trail, mutation lock) stays identical across surfaces rather
|
|
214
|
+
* than being duplicated here.
|
|
215
|
+
*/
|
|
216
|
+
export function setScopePreset(projectRoot, presetKey) {
|
|
217
|
+
const key = presetKey.trim();
|
|
218
|
+
const validKeys = scopePresetKeys();
|
|
219
|
+
if (!validKeys.includes(key)) {
|
|
220
|
+
throw new Error(`unknown preset ${JSON.stringify(presetKey)}; valid presets: ${validKeys.join(", ")}`);
|
|
221
|
+
}
|
|
222
|
+
const rules = subscriptionPreset(key);
|
|
223
|
+
return writeTriageScope(projectRoot, rules, { presetLabel: key });
|
|
224
|
+
}
|
|
203
225
|
//# sourceMappingURL=mutations.js.map
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export declare const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
|
|
2
1
|
export declare const CACHE_DIR_NAME = ".deft-cache";
|
|
3
2
|
export declare const CACHE_SOURCE = "github-issue";
|
|
4
3
|
export declare const CANDIDATES_RELPATH: readonly ["vbrief", ".eval", "candidates.jsonl"];
|
|
5
4
|
export declare const WIP_LIFECYCLE_DIRS: readonly ["pending", "active"];
|
|
6
5
|
export declare const AUDIT_LOG_REL_PATH = "meta/policy-changes.log";
|
|
7
|
-
export declare const DEFAULT_WIP_CAP =
|
|
6
|
+
export declare const DEFAULT_WIP_CAP = 20;
|
|
8
7
|
export declare const DEFAULT_RELIEF_AGE_DAYS = 30;
|
|
9
8
|
export declare const TRIAGE_SKILL_PATH = "skills/deft-directive-triage/SKILL.md";
|
|
10
9
|
export declare const WELCOME_AUDIT_TAG = "triage-welcome";
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
|
|
2
1
|
export const CACHE_DIR_NAME = ".deft-cache";
|
|
3
2
|
export const CACHE_SOURCE = "github-issue";
|
|
4
3
|
export const CANDIDATES_RELPATH = ["vbrief", ".eval", "candidates.jsonl"];
|
|
5
4
|
export const WIP_LIFECYCLE_DIRS = ["pending", "active"];
|
|
6
5
|
export const AUDIT_LOG_REL_PATH = "meta/policy-changes.log";
|
|
7
|
-
export const DEFAULT_WIP_CAP =
|
|
6
|
+
export const DEFAULT_WIP_CAP = 20;
|
|
8
7
|
export const DEFAULT_RELIEF_AGE_DAYS = 30;
|
|
9
8
|
export const TRIAGE_SKILL_PATH = "skills/deft-directive-triage/SKILL.md";
|
|
10
9
|
export const WELCOME_AUDIT_TAG = "triage-welcome";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./constants.js";
|
|
2
2
|
export { type DefaultModeOptions, formatWelcomeCommand, normalizeTaskPrefix, runDefaultMode, type WelcomeOutcome, } from "./default-mode.js";
|
|
3
|
+
export { DEFAULT_ONBOARD_PRESET, type OnboardOptions, type OnboardOutcome, runOnboardMode, } from "./onboard.js";
|
|
3
4
|
export { candidatesLogPath, classifyOnboarding, detectPriorState, type PriorState, pendingDecisionsNudgeLine, } from "./prior-state.js";
|
|
4
5
|
export { computeSummary, emitOneliner, formatOneLiner, formatSummary, type SummaryResult, } from "./summary.js";
|
|
5
6
|
export { appendAuditEntry, previewWipRelief, type ReliefPreview, subscriptionPreset, writeTriageScope, writeWipCap, } from "./writers.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from "./constants.js";
|
|
2
2
|
export { formatWelcomeCommand, normalizeTaskPrefix, runDefaultMode, } from "./default-mode.js";
|
|
3
|
+
export { DEFAULT_ONBOARD_PRESET, runOnboardMode, } from "./onboard.js";
|
|
3
4
|
export { candidatesLogPath, classifyOnboarding, detectPriorState, pendingDecisionsNudgeLine, } from "./prior-state.js";
|
|
4
5
|
export { computeSummary, emitOneliner, formatOneLiner, formatSummary, } from "./summary.js";
|
|
5
6
|
export { appendAuditEntry, previewWipRelief, subscriptionPreset, writeTriageScope, writeWipCap, } from "./writers.js";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Default triage-scope preset applied when `--onboard` is run without `--preset`. */
|
|
2
|
+
export declare const DEFAULT_ONBOARD_PRESET = "small";
|
|
3
|
+
export interface OnboardOptions {
|
|
4
|
+
/** Triage-scope preset key; defaults to {@link DEFAULT_ONBOARD_PRESET}. */
|
|
5
|
+
readonly preset?: string | null;
|
|
6
|
+
/** Explicit WIP cap to persist; omitted keeps the current/default cap. */
|
|
7
|
+
readonly wipCap?: number | null;
|
|
8
|
+
readonly output?: (line: string) => void;
|
|
9
|
+
readonly writeHistory?: boolean;
|
|
10
|
+
readonly taskPrefix?: string | null;
|
|
11
|
+
readonly selfHealFn?: (projectRoot: string) => void;
|
|
12
|
+
readonly now?: Date;
|
|
13
|
+
}
|
|
14
|
+
export interface OnboardOutcome {
|
|
15
|
+
readonly exitCode: number;
|
|
16
|
+
readonly presetApplied: string | null;
|
|
17
|
+
readonly triageScopeChanged: boolean;
|
|
18
|
+
readonly wipCapApplied: number | null;
|
|
19
|
+
readonly wipCapChanged: boolean;
|
|
20
|
+
readonly reliefOffered: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Non-interactive onboarding for `deft triage:welcome --onboard` (#2295).
|
|
24
|
+
*
|
|
25
|
+
* The welcome nudges point every fresh consumer at `--onboard`; this wires that
|
|
26
|
+
* command to the already-tested core writers instead of the old "not
|
|
27
|
+
* implemented" stub. It writes the chosen triage-scope preset and (optionally)
|
|
28
|
+
* a WIP cap via {@link writeTriageScope} / {@link writeWipCap} -- which already
|
|
29
|
+
* target the canonical `x-directive/policy` key and migrate any legacy bare
|
|
30
|
+
* block -- previews WIP relief when at/over cap, then prints a completion
|
|
31
|
+
* summary and the next-step guidance. Flag-driven by design: agents/CI pass
|
|
32
|
+
* `--preset` / `--wip-cap`; sensible defaults apply otherwise.
|
|
33
|
+
*/
|
|
34
|
+
export declare function runOnboardMode(projectRoot: string, options?: OnboardOptions): OnboardOutcome;
|
|
35
|
+
//# sourceMappingURL=onboard.d.ts.map
|