@deftai/directive-core 0.66.2 → 0.68.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/agents-md-advisory/evaluate.d.ts +44 -0
- package/dist/agents-md-advisory/evaluate.js +115 -0
- package/dist/agents-md-advisory/index.d.ts +2 -0
- package/dist/agents-md-advisory/index.js +2 -0
- package/dist/agents-md-budget/evaluate.d.ts +38 -0
- package/dist/agents-md-budget/evaluate.js +152 -0
- package/dist/agents-md-budget/index.d.ts +2 -0
- package/dist/agents-md-budget/index.js +2 -0
- package/dist/check/index.d.ts +1 -1
- package/dist/check/index.js +1 -1
- package/dist/check/orchestrator.d.ts +14 -4
- package/dist/check/orchestrator.js +30 -6
- package/dist/codebase/map.d.ts +1 -0
- package/dist/codebase/map.js +5 -2
- package/dist/doctor/checks.js +11 -11
- package/dist/doctor/constants.d.ts +7 -2
- package/dist/doctor/constants.js +17 -1
- package/dist/doctor/flags.js +5 -1
- package/dist/doctor/main.js +99 -8
- package/dist/doctor/payload-staleness.js +15 -6
- package/dist/doctor/types.d.ts +7 -0
- package/dist/forward-coverage/evaluate.d.ts +55 -0
- package/dist/forward-coverage/evaluate.js +254 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/init-deposit/constants.d.ts +14 -0
- package/dist/init-deposit/constants.js +10 -0
- package/dist/init-deposit/hygiene.d.ts +50 -0
- package/dist/init-deposit/hygiene.js +176 -0
- package/dist/init-deposit/init-deposit.d.ts +1 -0
- package/dist/init-deposit/init-deposit.js +7 -1
- package/dist/init-deposit/refresh.d.ts +2 -0
- package/dist/init-deposit/refresh.js +48 -30
- package/dist/init-deposit/scaffold.d.ts +3 -4
- package/dist/init-deposit/scaffold.js +3 -24
- package/dist/intake/github-auth-modes.d.ts +1 -0
- package/dist/intake/github-auth-modes.js +1 -0
- package/dist/intake/issue-ingest.d.ts +6 -2
- package/dist/intake/issue-ingest.js +65 -9
- package/dist/integration-e2e/helpers.d.ts +0 -1
- package/dist/integration-e2e/helpers.js +3 -7
- package/dist/layout/lifecycle-ref.d.ts +15 -0
- package/dist/layout/lifecycle-ref.js +55 -0
- package/dist/platform/agents-consumer-header.d.ts +13 -0
- package/dist/platform/agents-consumer-header.js +57 -0
- package/dist/platform/agents-md.d.ts +28 -0
- package/dist/platform/agents-md.js +38 -1
- package/dist/platform/index.d.ts +1 -0
- package/dist/platform/index.js +1 -0
- package/dist/policy/agents-md-advisory.d.ts +52 -0
- package/dist/policy/agents-md-advisory.js +63 -0
- package/dist/policy/agents-md-budget.d.ts +24 -0
- package/dist/policy/agents-md-budget.js +89 -0
- package/dist/policy/index.d.ts +1 -0
- package/dist/policy/index.js +1 -0
- package/dist/policy/resolve.js +56 -46
- package/dist/pr-merge-readiness/ci-gate.d.ts +28 -0
- package/dist/pr-merge-readiness/ci-gate.js +79 -0
- package/dist/pr-merge-readiness/compute.d.ts +15 -1
- package/dist/pr-merge-readiness/compute.js +129 -9
- package/dist/pr-merge-readiness/gh.d.ts +8 -0
- package/dist/pr-merge-readiness/gh.js +30 -5
- package/dist/pr-merge-readiness/index.d.ts +5 -1
- package/dist/pr-merge-readiness/index.js +3 -0
- package/dist/pr-merge-readiness/main.d.ts +3 -0
- package/dist/pr-merge-readiness/main.js +73 -6
- package/dist/pr-merge-readiness/mergeability.d.ts +43 -0
- package/dist/pr-merge-readiness/mergeability.js +105 -0
- package/dist/pr-merge-readiness/output.js +20 -0
- package/dist/pr-merge-readiness/slizard-gate.d.ts +47 -0
- package/dist/pr-merge-readiness/slizard-gate.js +119 -0
- package/dist/pr-monitor/index.d.ts +1 -1
- package/dist/pr-monitor/index.js +1 -1
- package/dist/pr-monitor/monitor.d.ts +8 -2
- package/dist/pr-monitor/monitor.js +35 -6
- package/dist/pr-wait-mergeable/wrappers.d.ts +12 -1
- package/dist/pr-wait-mergeable/wrappers.js +13 -5
- package/dist/pr-watch/constants.d.ts +33 -0
- package/dist/pr-watch/constants.js +33 -0
- package/dist/pr-watch/index.d.ts +6 -0
- package/dist/pr-watch/index.js +6 -0
- package/dist/pr-watch/main.d.ts +21 -0
- package/dist/pr-watch/main.js +206 -0
- package/dist/pr-watch/probe.d.ts +13 -0
- package/dist/pr-watch/probe.js +100 -0
- package/dist/pr-watch/types.d.ts +47 -0
- package/dist/pr-watch/types.js +2 -0
- package/dist/pr-watch/watch.d.ts +12 -0
- package/dist/pr-watch/watch.js +122 -0
- package/dist/preflight-cache/evaluate.d.ts +1 -0
- package/dist/preflight-cache/evaluate.js +17 -10
- package/dist/render/project-render.d.ts +16 -2
- package/dist/render/project-render.js +155 -97
- package/dist/scope/capacity-stamp.d.ts +24 -2
- package/dist/scope/capacity-stamp.js +80 -28
- package/dist/scope/decomposed-refs.js +2 -2
- package/dist/scope/project-definition-sync.js +3 -3
- package/dist/scope/vbrief-ref.d.ts +2 -1
- package/dist/scope/vbrief-ref.js +3 -2
- package/dist/spec-authority/constants.d.ts +6 -0
- package/dist/spec-authority/constants.js +11 -0
- package/dist/spec-authority/resolver.js +3 -3
- package/dist/swarm/finalize-cohort-cli.d.ts +5 -0
- package/dist/swarm/finalize-cohort-cli.js +100 -0
- package/dist/swarm/finalize-cohort.d.ts +39 -0
- package/dist/swarm/finalize-cohort.js +589 -0
- package/dist/swarm/index.d.ts +2 -0
- package/dist/swarm/index.js +2 -0
- package/dist/swarm/launch.d.ts +13 -0
- package/dist/swarm/launch.js +19 -7
- package/dist/swarm/routing-verify.d.ts +1 -1
- package/dist/swarm/routing-verify.js +11 -10
- package/dist/swarm/routing.d.ts +9 -0
- package/dist/swarm/routing.js +46 -0
- package/dist/swarm/verify-review-clean-cli.js +25 -1
- package/dist/swarm/verify-review-clean.d.ts +9 -1
- package/dist/swarm/verify-review-clean.js +76 -3
- package/dist/triage/queue/index.d.ts +1 -0
- package/dist/triage/queue/index.js +1 -0
- package/dist/triage/queue/project.d.ts +6 -1
- package/dist/triage/queue/project.js +9 -4
- package/dist/triage/queue/reconcile-live-state.d.ts +42 -0
- package/dist/triage/queue/reconcile-live-state.js +54 -0
- package/dist/triage/scope/mutations-core.js +91 -81
- package/dist/triage/scope/resolve.js +4 -3
- package/dist/triage/scope-drift/add-ignore.js +33 -32
- package/dist/triage/scope-drift/scope-rules.js +3 -3
- package/dist/triage/subscribe/index.js +51 -45
- package/dist/triage/welcome/writers.js +79 -64
- package/dist/vbrief-build/project-definition-io.js +8 -3
- package/dist/vbrief-validate/paths.js +8 -4
- package/dist/vbrief-validate/precutover.d.ts +1 -1
- package/dist/vbrief-validate/precutover.js +12 -10
- package/dist/verify-source/biome-config.d.ts +41 -0
- package/dist/verify-source/biome-config.js +97 -0
- package/dist/verify-source/index.d.ts +1 -0
- package/dist/verify-source/index.js +1 -0
- package/dist/xbrief-migrate/agents-header.d.ts +69 -0
- package/dist/xbrief-migrate/agents-header.js +179 -0
- package/dist/xbrief-migrate/fs-helpers.d.ts +3 -0
- package/dist/xbrief-migrate/fs-helpers.js +11 -0
- package/dist/xbrief-migrate/index.d.ts +1 -0
- package/dist/xbrief-migrate/index.js +1 -0
- package/dist/xbrief-migrate/migrate-project.js +29 -10
- package/package.json +15 -7
- package/dist/install-upgrade/index.d.ts +0 -13
- package/dist/install-upgrade/index.js +0 -251
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type RegionCounts } from "../agents-md-budget/evaluate.js";
|
|
2
|
+
import { type AgentsMdAdvisorySource } from "../policy/agents-md-advisory.js";
|
|
3
|
+
export type OutputStream = "stdout" | "stderr" | "none";
|
|
4
|
+
/**
|
|
5
|
+
* Result of the consumer AGENTS.md advisory evaluation (#2155).
|
|
6
|
+
*
|
|
7
|
+
* `code` is 0 in the DEFAULT advisory posture no matter what -- the advisory
|
|
8
|
+
* MUST NEVER fail-close a consumer build. Non-zero codes are only ever produced
|
|
9
|
+
* in the explicit `--enforce` opt-in posture (1 = over the hard cap the
|
|
10
|
+
* consumer asked for; 2 = a config problem that blocks an enforced check).
|
|
11
|
+
*/
|
|
12
|
+
export interface AdvisoryEvaluateResult {
|
|
13
|
+
readonly code: 0 | 1 | 2;
|
|
14
|
+
readonly message: string;
|
|
15
|
+
readonly stream: OutputStream;
|
|
16
|
+
/** True when the unmanaged region exceeds the soft budget. */
|
|
17
|
+
readonly over: boolean;
|
|
18
|
+
/** Region counts, or null when AGENTS.md was missing / unreadable / malformed. */
|
|
19
|
+
readonly counts: RegionCounts | null;
|
|
20
|
+
/** The resolved soft budget the unmanaged region was compared against. */
|
|
21
|
+
readonly softMaxLines: number;
|
|
22
|
+
/** Provenance of the soft budget (typed / default / default-on-error). */
|
|
23
|
+
readonly source: AgentsMdAdvisorySource;
|
|
24
|
+
}
|
|
25
|
+
export interface AdvisoryEvaluateOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Opt-in hard-cap posture (#1419 enforce tier). When true, an over-budget
|
|
28
|
+
* unmanaged region exits 1 and a config problem exits 2. Default (false) is
|
|
29
|
+
* the advisory posture that always exits 0.
|
|
30
|
+
*/
|
|
31
|
+
readonly enforce?: boolean;
|
|
32
|
+
/** Suppress the within-budget "OK" line (used by aggregate callers). */
|
|
33
|
+
readonly quiet?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Evaluate the consumer AGENTS.md against its soft, unmanaged-focused budget.
|
|
37
|
+
*
|
|
38
|
+
* Reuses the #645 region counter (`countRegions`) so the framework-owned
|
|
39
|
+
* managed section is EXCLUDED from the comparison -- only the consumer-authored
|
|
40
|
+
* unmanaged region is measured. In the default advisory posture the result code
|
|
41
|
+
* is always 0; `--enforce` promotes over-budget / config problems to non-zero.
|
|
42
|
+
*/
|
|
43
|
+
export declare function evaluate(projectRoot: string, options?: AdvisoryEvaluateOptions): AdvisoryEvaluateResult;
|
|
44
|
+
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { countRegions } from "../agents-md-budget/evaluate.js";
|
|
4
|
+
import { resolveAgentsMdAdvisory, } from "../policy/agents-md-advisory.js";
|
|
5
|
+
const GUIDANCE_LINE = " AGENTS.md is a map, not a manual (#1882): push project detail into a\n" +
|
|
6
|
+
" reference doc and leave a pointer, rather than growing AGENTS.md. See\n" +
|
|
7
|
+
" content/docs/good-agents-md.md.";
|
|
8
|
+
function overMessage(counts, softMax, enforce, fieldName) {
|
|
9
|
+
const over = counts.unmanaged - softMax;
|
|
10
|
+
if (enforce) {
|
|
11
|
+
return (`❌ agents-md-advisory: AGENTS.md unmanaged (project-authored) region is ` +
|
|
12
|
+
`${counts.unmanaged} lines, over the enforced cap of ${softMax} (OVER by ${over}).\n` +
|
|
13
|
+
`${GUIDANCE_LINE}\n` +
|
|
14
|
+
` Raise ${fieldName} in PROJECT-DEFINITION to accept the growth.`);
|
|
15
|
+
}
|
|
16
|
+
return (`⚠ agents-md-advisory: AGENTS.md unmanaged (project-authored) region is ` +
|
|
17
|
+
`${counts.unmanaged} lines, over the soft budget of ${softMax} (OVER by ${over}). ` +
|
|
18
|
+
"This is advisory only -- your build is NOT affected.\n" +
|
|
19
|
+
`${GUIDANCE_LINE}\n` +
|
|
20
|
+
` This is your knob: raise ${fieldName} in PROJECT-DEFINITION to accept the\n` +
|
|
21
|
+
" growth and silence this note.");
|
|
22
|
+
}
|
|
23
|
+
const FIELD_NAME = "plan.policy.agentsMdAdvisory.unmanagedSoftMaxLines";
|
|
24
|
+
/**
|
|
25
|
+
* Evaluate the consumer AGENTS.md against its soft, unmanaged-focused budget.
|
|
26
|
+
*
|
|
27
|
+
* Reuses the #645 region counter (`countRegions`) so the framework-owned
|
|
28
|
+
* managed section is EXCLUDED from the comparison -- only the consumer-authored
|
|
29
|
+
* unmanaged region is measured. In the default advisory posture the result code
|
|
30
|
+
* is always 0; `--enforce` promotes over-budget / config problems to non-zero.
|
|
31
|
+
*/
|
|
32
|
+
export function evaluate(projectRoot, options = {}) {
|
|
33
|
+
const root = resolve(projectRoot);
|
|
34
|
+
const enforce = options.enforce ?? false;
|
|
35
|
+
const quiet = options.quiet ?? false;
|
|
36
|
+
const advisory = resolveAgentsMdAdvisory(root);
|
|
37
|
+
const softMax = advisory.config.unmanagedSoftMaxLines;
|
|
38
|
+
const agentsPath = join(root, "AGENTS.md");
|
|
39
|
+
if (!existsSync(agentsPath)) {
|
|
40
|
+
const message = `agents-md-advisory: no AGENTS.md found at ${agentsPath}`;
|
|
41
|
+
return {
|
|
42
|
+
code: enforce ? 2 : 0,
|
|
43
|
+
message: enforce ? `❌ ${message}` : quiet ? "" : `${message} (advisory; skipped).`,
|
|
44
|
+
stream: enforce ? "stderr" : quiet ? "none" : "stdout",
|
|
45
|
+
over: false,
|
|
46
|
+
counts: null,
|
|
47
|
+
softMaxLines: softMax,
|
|
48
|
+
source: advisory.source,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
let text;
|
|
52
|
+
try {
|
|
53
|
+
text = readFileSync(agentsPath, { encoding: "utf8" });
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
const message = `agents-md-advisory: AGENTS.md at ${agentsPath} cannot be read: ${String(err)}`;
|
|
57
|
+
return {
|
|
58
|
+
code: enforce ? 2 : 0,
|
|
59
|
+
message: enforce ? `❌ ${message}` : quiet ? "" : `${message} (advisory; skipped).`,
|
|
60
|
+
stream: enforce ? "stderr" : quiet ? "none" : "stdout",
|
|
61
|
+
over: false,
|
|
62
|
+
counts: null,
|
|
63
|
+
softMaxLines: softMax,
|
|
64
|
+
source: advisory.source,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const regionResult = countRegions(text);
|
|
68
|
+
if ("error" in regionResult) {
|
|
69
|
+
const message = `agents-md-advisory: ${regionResult.error}`;
|
|
70
|
+
return {
|
|
71
|
+
code: enforce ? 2 : 0,
|
|
72
|
+
message: enforce ? `❌ ${message}` : quiet ? "" : `${message} (advisory; skipped).`,
|
|
73
|
+
stream: enforce ? "stderr" : quiet ? "none" : "stdout",
|
|
74
|
+
over: false,
|
|
75
|
+
counts: null,
|
|
76
|
+
softMaxLines: softMax,
|
|
77
|
+
source: advisory.source,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const counts = regionResult.counts;
|
|
81
|
+
const over = counts.unmanaged > softMax;
|
|
82
|
+
if (!over) {
|
|
83
|
+
if (quiet) {
|
|
84
|
+
return {
|
|
85
|
+
code: 0,
|
|
86
|
+
message: "",
|
|
87
|
+
stream: "none",
|
|
88
|
+
over: false,
|
|
89
|
+
counts,
|
|
90
|
+
softMaxLines: softMax,
|
|
91
|
+
source: advisory.source,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
code: 0,
|
|
96
|
+
message: `✓ agents-md-advisory: AGENTS.md unmanaged region ${counts.unmanaged}/${softMax} lines ` +
|
|
97
|
+
`within soft budget (managed ${counts.managed} excluded; advisory).`,
|
|
98
|
+
stream: "stdout",
|
|
99
|
+
over: false,
|
|
100
|
+
counts,
|
|
101
|
+
softMaxLines: softMax,
|
|
102
|
+
source: advisory.source,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
code: enforce ? 1 : 0,
|
|
107
|
+
message: overMessage(counts, softMax, enforce, FIELD_NAME),
|
|
108
|
+
stream: "stderr",
|
|
109
|
+
over: true,
|
|
110
|
+
counts,
|
|
111
|
+
softMaxLines: softMax,
|
|
112
|
+
source: advisory.source,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=evaluate.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type OutputStream = "stdout" | "stderr" | "none";
|
|
2
|
+
/** Result of verify:agents-md-budget evaluation; three-state exit contract. */
|
|
3
|
+
export interface EvaluateResult {
|
|
4
|
+
readonly code: 0 | 1 | 2;
|
|
5
|
+
readonly message: string;
|
|
6
|
+
readonly stream: OutputStream;
|
|
7
|
+
}
|
|
8
|
+
export interface EvaluateOptions {
|
|
9
|
+
readonly quiet?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Per-region line counts of an AGENTS.md file. */
|
|
12
|
+
export interface RegionCounts {
|
|
13
|
+
readonly total: number;
|
|
14
|
+
readonly managed: number;
|
|
15
|
+
readonly unmanaged: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Split AGENTS.md into managed / unmanaged line counts.
|
|
19
|
+
*
|
|
20
|
+
* Returns `{ counts }` on success, or `{ error }` when the managed markers are
|
|
21
|
+
* malformed (exactly one marker present, or close-before-open). A file with no
|
|
22
|
+
* markers at all is valid: the whole file counts as unmanaged.
|
|
23
|
+
*/
|
|
24
|
+
export declare function countRegions(text: string): {
|
|
25
|
+
counts: RegionCounts;
|
|
26
|
+
} | {
|
|
27
|
+
error: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Pure evaluator for the AGENTS.md line-budget ratchet gate (#645).
|
|
31
|
+
*
|
|
32
|
+
* Counts the managed section and the unmanaged region separately (the #1309
|
|
33
|
+
* propagation duplicates content across the marker) and fails when either
|
|
34
|
+
* region exceeds its typed per-region budget. Ships green because the budget is
|
|
35
|
+
* seeded at current size; growth past the ratchet fails.
|
|
36
|
+
*/
|
|
37
|
+
export declare function evaluate(projectRoot: string, options?: EvaluateOptions): EvaluateResult;
|
|
38
|
+
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { AGENTS_MANAGED_CLOSE } from "../platform/constants.js";
|
|
4
|
+
import { resolveAgentsMdBudget } from "../policy/agents-md-budget.js";
|
|
5
|
+
const OPEN_MARKER_PREFIX = "<!-- deft:managed-section";
|
|
6
|
+
/**
|
|
7
|
+
* Split AGENTS.md into managed / unmanaged line counts.
|
|
8
|
+
*
|
|
9
|
+
* Returns `{ counts }` on success, or `{ error }` when the managed markers are
|
|
10
|
+
* malformed (exactly one marker present, or close-before-open). A file with no
|
|
11
|
+
* markers at all is valid: the whole file counts as unmanaged.
|
|
12
|
+
*/
|
|
13
|
+
export function countRegions(text) {
|
|
14
|
+
const lines = text.replace(/\r\n/g, "\n").split("\n");
|
|
15
|
+
// Ignore the trailing empty element produced by a final newline.
|
|
16
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
17
|
+
lines.pop();
|
|
18
|
+
}
|
|
19
|
+
const total = lines.length;
|
|
20
|
+
const openLine = lines.findIndex((l) => l.startsWith(OPEN_MARKER_PREFIX));
|
|
21
|
+
const closeLine = lines.findIndex((l) => l.trim().startsWith(AGENTS_MANAGED_CLOSE));
|
|
22
|
+
const openCount = lines.filter((l) => l.startsWith(OPEN_MARKER_PREFIX)).length;
|
|
23
|
+
const closeCount = lines.filter((l) => l.trim().startsWith(AGENTS_MANAGED_CLOSE)).length;
|
|
24
|
+
if (openLine === -1 && closeLine === -1) {
|
|
25
|
+
return { counts: { total, managed: 0, unmanaged: total } };
|
|
26
|
+
}
|
|
27
|
+
// Malformed if a marker is missing, close precedes open, or either marker is
|
|
28
|
+
// duplicated -- the contract promises exactly one open/close pair.
|
|
29
|
+
if (openLine === -1 ||
|
|
30
|
+
closeLine === -1 ||
|
|
31
|
+
closeLine < openLine ||
|
|
32
|
+
openCount > 1 ||
|
|
33
|
+
closeCount > 1) {
|
|
34
|
+
return {
|
|
35
|
+
error: "AGENTS.md managed-section markers are malformed " +
|
|
36
|
+
`(open@${openLine === -1 ? "none" : openLine + 1}×${openCount}, ` +
|
|
37
|
+
`close@${closeLine === -1 ? "none" : closeLine + 1}×${closeCount}); ` +
|
|
38
|
+
"expected a single <!-- deft:managed-section ... --> ... " +
|
|
39
|
+
"<!-- /deft:managed-section --> pair.",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const managed = closeLine - openLine + 1;
|
|
43
|
+
return { counts: { total, managed, unmanaged: total - managed } };
|
|
44
|
+
}
|
|
45
|
+
function formatRefusal(counts, managedMax, unmanagedMax, projectRoot) {
|
|
46
|
+
const over = [];
|
|
47
|
+
if (counts.managed > managedMax) {
|
|
48
|
+
over.push(` managed region: ${counts.managed}/${managedMax} lines (OVER by ${counts.managed - managedMax})`);
|
|
49
|
+
}
|
|
50
|
+
if (counts.unmanaged > unmanagedMax) {
|
|
51
|
+
over.push(` unmanaged region: ${counts.unmanaged}/${unmanagedMax} lines (OVER by ${counts.unmanaged - unmanagedMax})`);
|
|
52
|
+
}
|
|
53
|
+
return (`❌ verify:agents-md-budget: AGENTS.md grew past its ratchet ` +
|
|
54
|
+
`(project_root=${projectRoot}).\n` +
|
|
55
|
+
`${over.join("\n")}\n` +
|
|
56
|
+
" AGENTS.md is a map, not a manual (#1882): push detail into a\n" +
|
|
57
|
+
" reference doc (main.md / a pack / docs/) and leave a pointer,\n" +
|
|
58
|
+
" rather than expanding AGENTS.md. See REFERENCES.md.\n" +
|
|
59
|
+
" If the growth is deliberate, raise the matching line in\n" +
|
|
60
|
+
" plan.policy.agentsMdBudget in PROJECT-DEFINITION (a reviewed diff). (#645)");
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Pure evaluator for the AGENTS.md line-budget ratchet gate (#645).
|
|
64
|
+
*
|
|
65
|
+
* Counts the managed section and the unmanaged region separately (the #1309
|
|
66
|
+
* propagation duplicates content across the marker) and fails when either
|
|
67
|
+
* region exceeds its typed per-region budget. Ships green because the budget is
|
|
68
|
+
* seeded at current size; growth past the ratchet fails.
|
|
69
|
+
*/
|
|
70
|
+
export function evaluate(projectRoot, options = {}) {
|
|
71
|
+
const root = resolve(projectRoot);
|
|
72
|
+
const quiet = options.quiet ?? false;
|
|
73
|
+
const budgetResult = resolveAgentsMdBudget(root);
|
|
74
|
+
if (budgetResult.source === "default-on-error") {
|
|
75
|
+
return {
|
|
76
|
+
code: 2,
|
|
77
|
+
message: `❌ verify:agents-md-budget: PROJECT-DEFINITION malformed: ${budgetResult.error}`,
|
|
78
|
+
stream: "stderr",
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const agentsPath = join(root, "AGENTS.md");
|
|
82
|
+
if (!existsSync(agentsPath)) {
|
|
83
|
+
return {
|
|
84
|
+
code: 2,
|
|
85
|
+
message: `❌ verify:agents-md-budget: AGENTS.md not found at ${agentsPath}`,
|
|
86
|
+
stream: "stderr",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
let text;
|
|
90
|
+
try {
|
|
91
|
+
text = readFileSync(agentsPath, { encoding: "utf8" });
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
return {
|
|
95
|
+
code: 2,
|
|
96
|
+
message: `❌ verify:agents-md-budget: AGENTS.md at ${agentsPath} cannot be read: ${String(err)}`,
|
|
97
|
+
stream: "stderr",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const regionResult = countRegions(text);
|
|
101
|
+
if ("error" in regionResult) {
|
|
102
|
+
return {
|
|
103
|
+
code: 2,
|
|
104
|
+
message: `❌ verify:agents-md-budget: ${regionResult.error}`,
|
|
105
|
+
stream: "stderr",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const counts = regionResult.counts;
|
|
109
|
+
if (budgetResult.source === "unset") {
|
|
110
|
+
if (quiet) {
|
|
111
|
+
return { code: 0, message: "", stream: "none" };
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
code: 0,
|
|
115
|
+
message: "⚠ verify:agents-md-budget: no plan.policy.agentsMdBudget configured " +
|
|
116
|
+
`(managed=${counts.managed}, unmanaged=${counts.unmanaged} lines).\n` +
|
|
117
|
+
" Seed a ratchet at current size to freeze growth (#645): set\n" +
|
|
118
|
+
" plan.policy.agentsMdBudget.{managedMaxLines,unmanagedMaxLines} in " +
|
|
119
|
+
"PROJECT-DEFINITION.",
|
|
120
|
+
stream: "stderr",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/* v8 ignore start -- defensive: source "typed" always carries a non-null budget. */
|
|
124
|
+
if (budgetResult.budget === null) {
|
|
125
|
+
return {
|
|
126
|
+
code: 2,
|
|
127
|
+
message: "❌ verify:agents-md-budget: unexpected null budget for typed source",
|
|
128
|
+
stream: "stderr",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/* v8 ignore stop */
|
|
132
|
+
const budget = budgetResult.budget;
|
|
133
|
+
const overManaged = counts.managed > budget.managedMaxLines;
|
|
134
|
+
const overUnmanaged = counts.unmanaged > budget.unmanagedMaxLines;
|
|
135
|
+
if (!overManaged && !overUnmanaged) {
|
|
136
|
+
if (quiet) {
|
|
137
|
+
return { code: 0, message: "", stream: "none" };
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
code: 0,
|
|
141
|
+
message: `✓ verify:agents-md-budget: managed ${counts.managed}/${budget.managedMaxLines}, ` +
|
|
142
|
+
`unmanaged ${counts.unmanaged}/${budget.unmanagedMaxLines} lines (within ratchet).`,
|
|
143
|
+
stream: "stdout",
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
code: 1,
|
|
148
|
+
message: formatRefusal(counts, budget.managedMaxLines, budget.unmanagedMaxLines, root),
|
|
149
|
+
stream: "stderr",
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=evaluate.js.map
|
package/dist/check/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export type { CheckOrchestratorSeams } from "./orchestrator.js";
|
|
2
|
-
export { dispatchTaskCheck, isFrameworkSourceContext, resolveCheckTarget } from "./orchestrator.js";
|
|
2
|
+
export { dispatchTaskCheck, isFrameworkRepoRoot, isFrameworkSourceContext, resolveCheckTarget, } from "./orchestrator.js";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/check/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { dispatchTaskCheck, isFrameworkSourceContext, resolveCheckTarget } from "./orchestrator.js";
|
|
1
|
+
export { dispatchTaskCheck, isFrameworkRepoRoot, isFrameworkSourceContext, resolveCheckTarget, } from "./orchestrator.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -24,13 +24,23 @@ export interface CheckOrchestratorSeams {
|
|
|
24
24
|
error?: Error;
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* True when `path` is the directive framework source checkout root (not a
|
|
29
|
+
* vendored `.deft/core` content deposit). Used to distinguish a maintainer
|
|
30
|
+
* running `task check` from a subdirectory (#2220) from a consumer install.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isFrameworkRepoRoot(path: string): boolean;
|
|
27
33
|
/**
|
|
28
34
|
* Return true when running in the framework's own source checkout (#1519).
|
|
29
35
|
*
|
|
30
|
-
* Mirrors `is_framework_source_context` from _project_context.py
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
36
|
+
* Mirrors `is_framework_source_context` from _project_context.py with one
|
|
37
|
+
* extension (#2220): when the Taskfile lives at the framework repo root,
|
|
38
|
+
* `task check` may be invoked from a subdirectory (`USER_WORKING_DIR` !=
|
|
39
|
+
* `TASKFILE_DIR`). Those invocations must still route to
|
|
40
|
+
* `check:framework-source` so the biome lane runs. We do NOT resolve
|
|
41
|
+
* symlinks on the framework root -- a consumer project may symlink
|
|
42
|
+
* `.deft/core` to a local framework checkout and should still run the
|
|
43
|
+
* consumer-safe gate (the deposit path lacks `packages/cli`).
|
|
34
44
|
*/
|
|
35
45
|
export declare function isFrameworkSourceContext(frameworkRoot: string, projectRoot: string): boolean;
|
|
36
46
|
/**
|
|
@@ -12,17 +12,41 @@
|
|
|
12
12
|
* 2 -- config error (missing args, task spawn error, etc.)
|
|
13
13
|
*/
|
|
14
14
|
import { spawnSync } from "node:child_process";
|
|
15
|
-
import {
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import { join, resolve, sep } from "node:path";
|
|
17
|
+
/**
|
|
18
|
+
* True when `path` is the directive framework source checkout root (not a
|
|
19
|
+
* vendored `.deft/core` content deposit). Used to distinguish a maintainer
|
|
20
|
+
* running `task check` from a subdirectory (#2220) from a consumer install.
|
|
21
|
+
*/
|
|
22
|
+
export function isFrameworkRepoRoot(path) {
|
|
23
|
+
const root = resolve(path);
|
|
24
|
+
return (existsSync(join(root, "packages", "cli", "package.json")) &&
|
|
25
|
+
existsSync(join(root, "biome.json")) &&
|
|
26
|
+
existsSync(join(root, "Taskfile.yml")));
|
|
27
|
+
}
|
|
16
28
|
/**
|
|
17
29
|
* Return true when running in the framework's own source checkout (#1519).
|
|
18
30
|
*
|
|
19
|
-
* Mirrors `is_framework_source_context` from _project_context.py
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
31
|
+
* Mirrors `is_framework_source_context` from _project_context.py with one
|
|
32
|
+
* extension (#2220): when the Taskfile lives at the framework repo root,
|
|
33
|
+
* `task check` may be invoked from a subdirectory (`USER_WORKING_DIR` !=
|
|
34
|
+
* `TASKFILE_DIR`). Those invocations must still route to
|
|
35
|
+
* `check:framework-source` so the biome lane runs. We do NOT resolve
|
|
36
|
+
* symlinks on the framework root -- a consumer project may symlink
|
|
37
|
+
* `.deft/core` to a local framework checkout and should still run the
|
|
38
|
+
* consumer-safe gate (the deposit path lacks `packages/cli`).
|
|
23
39
|
*/
|
|
24
40
|
export function isFrameworkSourceContext(frameworkRoot, projectRoot) {
|
|
25
|
-
|
|
41
|
+
const fw = resolve(frameworkRoot);
|
|
42
|
+
const pr = resolve(projectRoot);
|
|
43
|
+
if (fw === pr) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (!isFrameworkRepoRoot(fw)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return pr.startsWith(`${fw}${sep}`);
|
|
26
50
|
}
|
|
27
51
|
/**
|
|
28
52
|
* Select the Taskfile target for the given context.
|
package/dist/codebase/map.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const GENERATED_SENTINEL = "AUTO-GENERATED by task codebase:map";
|
|
2
2
|
export declare const DEFAULT_OUTPUT_PATH = ".planning/codebase/MAP.md";
|
|
3
3
|
export declare const BANNER_TEMPLATE: string;
|
|
4
|
+
export declare function markdownText(value: unknown): string;
|
|
4
5
|
export declare function projectionOutputPath(projectRoot: string, explicitOutput?: string | null): string;
|
|
5
6
|
export declare function renderCodebaseMap(artifact: Record<string, unknown>): string;
|
|
6
7
|
export declare function isDeftGenerated(path: string): boolean;
|
package/dist/codebase/map.js
CHANGED
|
@@ -13,9 +13,12 @@ export const BANNER_TEMPLATE = "<!-- AUTO-GENERATED by task codebase:map -- DO N
|
|
|
13
13
|
"<!-- Source of truth: vbrief/PROJECT-DEFINITION.vbrief.json " +
|
|
14
14
|
"plan.architecture.codeStructure -->\n" +
|
|
15
15
|
"<!-- Regenerate with: task codebase:map -->\n";
|
|
16
|
-
function markdownText(value) {
|
|
16
|
+
export function markdownText(value) {
|
|
17
17
|
const text = value === null || value === undefined ? "" : String(value);
|
|
18
|
-
|
|
18
|
+
// Escape the backslash escape character FIRST, then the `|` table delimiter.
|
|
19
|
+
// Escaping `|` alone lets a pre-existing backslash bypass the delimiter
|
|
20
|
+
// escape (CodeQL js/incomplete-sanitization).
|
|
21
|
+
return text.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\n/g, " ").trim();
|
|
19
22
|
}
|
|
20
23
|
function code(value) {
|
|
21
24
|
const text = markdownText(value);
|
package/dist/doctor/checks.js
CHANGED
|
@@ -34,14 +34,14 @@ export function checkQuickStartResolves(projectRoot, installRoot, seams = {}) {
|
|
|
34
34
|
`install root is '${installRoot}' but the file is missing. ` +
|
|
35
35
|
"Run `.deft/core/run agents:refresh` (Unix) / " +
|
|
36
36
|
"`.deft\\core\\run agents:refresh` (Windows) to align AGENTS.md " +
|
|
37
|
-
"with the on-disk install root, OR run `
|
|
37
|
+
"with the on-disk install root, OR run `deft update` to " +
|
|
38
38
|
"re-pull the framework if the on-disk install is missing. " +
|
|
39
39
|
"See UPGRADING.md for the canonical drift-repair walkthrough.",
|
|
40
40
|
data: {
|
|
41
41
|
path: qsPath,
|
|
42
42
|
install_root: installRoot,
|
|
43
43
|
suggested_fix: ".deft/core/run agents:refresh",
|
|
44
|
-
suggested_fix_alt: "
|
|
44
|
+
suggested_fix_alt: "deft update",
|
|
45
45
|
},
|
|
46
46
|
};
|
|
47
47
|
}
|
|
@@ -89,13 +89,13 @@ export function checkSkillPathsResolve(projectRoot, agentsMdText, seams = {}) {
|
|
|
89
89
|
status: "fail",
|
|
90
90
|
detail: `${missing.length} skill path(s) do not resolve; ${redirectStubs.length} stub redirect(s). ` +
|
|
91
91
|
`${parts.join("; ")}. Run \`.deft/core/run agents:refresh\` (Unix) / ` +
|
|
92
|
-
"`.deft\\core\\run agents:refresh` (Windows) to rewrite the managed AGENTS.md block so skill paths match the on-disk framework, OR run `
|
|
92
|
+
"`.deft\\core\\run agents:refresh` (Windows) to rewrite the managed AGENTS.md block so skill paths match the on-disk framework, OR run `deft update` if the on-disk skills are missing entirely. See UPGRADING.md for the drift-repair walkthrough.",
|
|
93
93
|
data: {
|
|
94
94
|
referenced,
|
|
95
95
|
missing,
|
|
96
96
|
redirect_stubs: redirectStubs,
|
|
97
97
|
suggested_fix: ".deft/core/run agents:refresh",
|
|
98
|
-
suggested_fix_alt: "
|
|
98
|
+
suggested_fix_alt: "deft update",
|
|
99
99
|
},
|
|
100
100
|
};
|
|
101
101
|
}
|
|
@@ -111,7 +111,7 @@ export function checkManifestAgreement(projectRoot, installRoot, seams = {}) {
|
|
|
111
111
|
return {
|
|
112
112
|
name: "manifest-agreement",
|
|
113
113
|
status: "fail",
|
|
114
|
-
detail: `Two install manifests disagree: .deft/core/VERSION (tag='${coreVer}') vs legacy .deft/VERSION (tag='${legacyVer}'). The canonical manifest is .deft/core/VERSION -- run \`
|
|
114
|
+
detail: `Two install manifests disagree: .deft/core/VERSION (tag='${coreVer}') vs legacy .deft/VERSION (tag='${legacyVer}'). The canonical manifest is .deft/core/VERSION -- run \`deft update\` to migrate the stale .deft/VERSION (backed up as .deft/VERSION.premigrate). See UPGRADING.md for the canonical drift-repair walkthrough.`,
|
|
115
115
|
data: {
|
|
116
116
|
dual_manifest_drift: true,
|
|
117
117
|
core_manifest_path: coreManifest,
|
|
@@ -119,7 +119,7 @@ export function checkManifestAgreement(projectRoot, installRoot, seams = {}) {
|
|
|
119
119
|
core_version: coreVer,
|
|
120
120
|
legacy_version: legacyVer,
|
|
121
121
|
authoritative: "manifest",
|
|
122
|
-
suggested_fix: "
|
|
122
|
+
suggested_fix: "deft update",
|
|
123
123
|
},
|
|
124
124
|
};
|
|
125
125
|
}
|
|
@@ -149,13 +149,13 @@ export function checkManifestAgreement(projectRoot, installRoot, seams = {}) {
|
|
|
149
149
|
return {
|
|
150
150
|
name: "manifest-agreement",
|
|
151
151
|
status: "fail",
|
|
152
|
-
detail: `Bare .deft-version exists at ${barePath} but YAML manifest is missing at ${expectedManifestPath}. Run \`
|
|
152
|
+
detail: `Bare .deft-version exists at ${barePath} but YAML manifest is missing at ${expectedManifestPath}. Run \`deft update\` to write the canonical manifest (#1046 PR-B AC-4). See UPGRADING.md for the v0.27.x -> v0.28 transition walkthrough.`,
|
|
153
153
|
data: {
|
|
154
154
|
manifest_path: manifestPath,
|
|
155
155
|
expected_manifest_path: expectedManifestPath,
|
|
156
156
|
bare_path: barePath,
|
|
157
157
|
bare_value: bareText?.trim() ?? null,
|
|
158
|
-
suggested_fix: "
|
|
158
|
+
suggested_fix: "deft update",
|
|
159
159
|
},
|
|
160
160
|
};
|
|
161
161
|
}
|
|
@@ -165,7 +165,7 @@ export function checkManifestAgreement(projectRoot, installRoot, seams = {}) {
|
|
|
165
165
|
return {
|
|
166
166
|
name: "manifest-agreement",
|
|
167
167
|
status: "pass",
|
|
168
|
-
detail: `YAML manifest at ${manifestPath} present; bare .deft-version absent (derived value: '${derived}' from manifest tag). Run \`
|
|
168
|
+
detail: `YAML manifest at ${manifestPath} present; bare .deft-version absent (derived value: '${derived}' from manifest tag). Run \`deft update\` to regenerate the derivative.`,
|
|
169
169
|
data: {
|
|
170
170
|
manifest_path: manifestPath,
|
|
171
171
|
manifest,
|
|
@@ -205,14 +205,14 @@ export function checkManifestAgreement(projectRoot, installRoot, seams = {}) {
|
|
|
205
205
|
return {
|
|
206
206
|
name: "manifest-agreement",
|
|
207
207
|
status: "fail",
|
|
208
|
-
detail: `Drift detected: YAML manifest tag='${derived}' does NOT agree with bare .deft-version='${bareValue}'. Per #1046 PR-B AC-4 the YAML manifest is the canonical source -- run \`
|
|
208
|
+
detail: `Drift detected: YAML manifest tag='${derived}' does NOT agree with bare .deft-version='${bareValue}'. Per #1046 PR-B AC-4 the YAML manifest is the canonical source -- run \`deft update\` to regenerate the bare derivative from the manifest, OR manually update ${manifestPath} if the bare value is correct. See UPGRADING.md for the canonical drift-repair walkthrough.`,
|
|
209
209
|
data: {
|
|
210
210
|
manifest_path: manifestPath,
|
|
211
211
|
bare_path: barePath,
|
|
212
212
|
derived_version: derived,
|
|
213
213
|
bare_value: bareValue,
|
|
214
214
|
authoritative: "manifest",
|
|
215
|
-
suggested_fix: "
|
|
215
|
+
suggested_fix: "deft update",
|
|
216
216
|
},
|
|
217
217
|
};
|
|
218
218
|
}
|
|
@@ -6,7 +6,11 @@ export declare const DEPRECATED_REDIRECT_SENTINEL = "<!-- deft:deprecated-redire
|
|
|
6
6
|
export declare const DEPRECATED_SKILL_REDIRECT_SENTINEL = "<!-- deft:deprecated-skill-redirect -->";
|
|
7
7
|
export declare const REDIRECT_STUB_HEADER_LINES = 8;
|
|
8
8
|
export declare const TASKFILE_INCLUDE_SNIPPET = "version: '3'\n\nincludes:\n deft:\n taskfile: ./.deft/core/Taskfile.yml\n optional: true\n";
|
|
9
|
-
export declare const DOCTOR_ALLOWED_FLAGS: readonly ["--session", "--fix", "--repair", "--repair-taskfile", "--json", "--quiet", "--full", "--project-root", "-h", "--help"];
|
|
9
|
+
export declare const DOCTOR_ALLOWED_FLAGS: readonly ["--session", "--fix", "--repair", "--repair-taskfile", "--json", "--quiet", "--full", "--network", "--project-root", "-h", "--help"];
|
|
10
|
+
/** npm consumer deposit after #2022 Phase 3 -- Python scripts/ tree is intentionally absent. */
|
|
11
|
+
export declare const NPM_PACKAGE_NAME = "@deftai/directive";
|
|
12
|
+
export declare const NETWORK_DISCLOSURE_LINE: string;
|
|
13
|
+
export declare const PAYLOAD_STALENESS_OFFLINE_SKIP_MESSAGE: string;
|
|
10
14
|
export declare const EXPECTED_FRAMEWORK_DIRS: readonly ["tasks", "scripts", "vbrief"];
|
|
11
15
|
/** npm consumer deposit after #2022 Phase 3 -- Python scripts/ tree is intentionally absent. */
|
|
12
16
|
export declare const CONSUMER_FRAMEWORK_DIRS: readonly ["tasks", "vbrief"];
|
|
@@ -14,7 +18,8 @@ export declare const DEFT_REPO_POSITIVE_MARKERS: readonly ["content/templates/ag
|
|
|
14
18
|
export declare const EXPECTED_CONTENT_DIRS: readonly ["languages", "strategies", "skills", "templates"];
|
|
15
19
|
/** Post-freeze canonical upgrade path (#1997 / #2003 / #1912). */
|
|
16
20
|
export declare const CANONICAL_UPGRADE_COMMAND = "npm i -g @deftai/directive@latest";
|
|
17
|
-
|
|
21
|
+
/** Vendored npm-managed deposit: global bump plus in-place `.deft/core/` refresh (#2115). */
|
|
22
|
+
export declare const VENDORED_NPM_DEPOSIT_UPGRADE_COMMAND = "npm i -g @deftai/directive@latest && deft update";
|
|
18
23
|
export declare const CLEAN_WINDOW_HOURS = 24;
|
|
19
24
|
export declare const DIRTY_WINDOW_HOURS = 4;
|
|
20
25
|
export declare const ENV_STATE_PATH = "DEFT_DOCTOR_STATE_PATH";
|
package/dist/doctor/constants.js
CHANGED
|
@@ -20,10 +20,25 @@ export const DOCTOR_ALLOWED_FLAGS = [
|
|
|
20
20
|
"--json",
|
|
21
21
|
"--quiet",
|
|
22
22
|
"--full",
|
|
23
|
+
"--network",
|
|
23
24
|
"--project-root",
|
|
24
25
|
"-h",
|
|
25
26
|
"--help",
|
|
26
27
|
];
|
|
28
|
+
/** npm consumer deposit after #2022 Phase 3 -- Python scripts/ tree is intentionally absent. */
|
|
29
|
+
export const NPM_PACKAGE_NAME = "@deftai/directive";
|
|
30
|
+
// #2182: payload-staleness is the only doctor check that can reach a network
|
|
31
|
+
// endpoint (git ls-remote against the framework's git remote, falling back to
|
|
32
|
+
// `npm view` against the npm registry). It is OFF by default (offline tier)
|
|
33
|
+
// and requires the explicit `--network` flag; this line discloses exactly
|
|
34
|
+
// which tool + registry class it may contact BEFORE the check runs, and the
|
|
35
|
+
// skip line tells an offline run how to opt in.
|
|
36
|
+
export const NETWORK_DISCLOSURE_LINE = "[deft doctor] --network: this run may contact your git remote (framework " +
|
|
37
|
+
"repo host) and, as a fallback, the npm registry (registry.npmjs.org) to " +
|
|
38
|
+
`look up the latest ${NPM_PACKAGE_NAME} version.`;
|
|
39
|
+
export const PAYLOAD_STALENESS_OFFLINE_SKIP_MESSAGE = "skip -- offline tier (default). Run `deft doctor --network` to check " +
|
|
40
|
+
"framework currency against your git remote and the npm registry " +
|
|
41
|
+
"(discloses tool + registry before contacting either).";
|
|
27
42
|
// Engine / lifecycle dirs that stay at the framework root (NOT relocated by
|
|
28
43
|
// #1875). Shippable-content dirs moved under content/ -- see EXPECTED_CONTENT_DIRS.
|
|
29
44
|
export const EXPECTED_FRAMEWORK_DIRS = ["tasks", "scripts", "vbrief"];
|
|
@@ -45,7 +60,8 @@ export const DEFT_REPO_POSITIVE_MARKERS = [
|
|
|
45
60
|
export const EXPECTED_CONTENT_DIRS = ["languages", "strategies", "skills", "templates"];
|
|
46
61
|
/** Post-freeze canonical upgrade path (#1997 / #2003 / #1912). */
|
|
47
62
|
export const CANONICAL_UPGRADE_COMMAND = "npm i -g @deftai/directive@latest";
|
|
48
|
-
|
|
63
|
+
/** Vendored npm-managed deposit: global bump plus in-place `.deft/core/` refresh (#2115). */
|
|
64
|
+
export const VENDORED_NPM_DEPOSIT_UPGRADE_COMMAND = `${CANONICAL_UPGRADE_COMMAND} && deft update`;
|
|
49
65
|
export const CLEAN_WINDOW_HOURS = 24;
|
|
50
66
|
export const DIRTY_WINDOW_HOURS = 4;
|
|
51
67
|
export const ENV_STATE_PATH = "DEFT_DOCTOR_STATE_PATH";
|