@unbrained/pm-cli 2026.6.11 → 2026.6.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/cli/commands/completion.js +20 -8
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/create.js +6 -3
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/docs.d.ts +2 -0
- package/dist/cli/commands/docs.js +2 -2
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/files.d.ts +2 -0
- package/dist/cli/commands/files.js +2 -2
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/health.d.ts +1 -1
- package/dist/cli/commands/health.js +77 -2
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history-repair.d.ts +36 -0
- package/dist/cli/commands/history-repair.js +68 -3
- package/dist/cli/commands/history-repair.js.map +1 -1
- package/dist/cli/commands/index.d.ts +1 -1
- package/dist/cli/commands/index.js +3 -3
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/linked-artifacts.d.ts +18 -0
- package/dist/cli/commands/linked-artifacts.js +26 -3
- package/dist/cli/commands/linked-artifacts.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +6 -0
- package/dist/cli/commands/plan.js +93 -32
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +20 -0
- package/dist/cli/commands/validate.js +292 -28
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/help-content.js +7 -3
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/register-mutation.js +47 -16
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +10 -2
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +16 -16
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli-bundle/chunks/{chunk-P2PSODAQ.js → chunk-35P4GT6E.js} +110 -9
- package/dist/cli-bundle/chunks/chunk-35P4GT6E.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-B65UUCGQ.js → chunk-37CYVF73.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-J3GD64J2.js → chunk-7AMK6DOW.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-J3GD64J2.js.map → chunk-7AMK6DOW.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-IKOH24GZ.js → chunk-AX4GEVQC.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-IKOH24GZ.js.map → chunk-AX4GEVQC.js.map} +2 -2
- package/dist/cli-bundle/chunks/chunk-C6SAP27O.js +187 -0
- package/dist/cli-bundle/chunks/chunk-C6SAP27O.js.map +1 -0
- package/dist/cli-bundle/chunks/chunk-EKS6O2IR.js +217 -0
- package/dist/cli-bundle/chunks/chunk-EKS6O2IR.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-PSD7F7DX.js → chunk-KBPQHXWG.js} +17 -4
- package/dist/cli-bundle/chunks/chunk-KBPQHXWG.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-3SLOMKCJ.js → chunk-L5EPZQIC.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-NAWVUHXH.js +220 -0
- package/dist/cli-bundle/chunks/chunk-NAWVUHXH.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-UOO6BYIA.js → chunk-PNYAAB4S.js} +21 -188
- package/dist/cli-bundle/chunks/chunk-PNYAAB4S.js.map +1 -0
- package/dist/cli-bundle/chunks/chunk-R2OUQVBK.js +190 -0
- package/dist/cli-bundle/chunks/chunk-R2OUQVBK.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-LCSCXBGT.js → chunk-R4VWYWRN.js} +19 -193
- package/dist/cli-bundle/chunks/chunk-R4VWYWRN.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-7RIT3OCD.js → chunk-SO55HRA5.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FXRU333M.js → chunk-UIG4TW2H.js} +110 -9
- package/dist/cli-bundle/chunks/chunk-UIG4TW2H.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-E5DUIJA4.js → chunk-WPDMBIX6.js} +16 -3
- package/dist/cli-bundle/chunks/chunk-WPDMBIX6.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-IH4MBKK7.js → chunk-XWMF3POR.js} +2 -2
- package/dist/cli-bundle/chunks/{contracts-3NKWYKKU.js → contracts-2G66IGIA.js} +2 -2
- package/dist/cli-bundle/chunks/{contracts-MIXBWJIB.js → contracts-PJCHYSO5.js} +2 -2
- package/dist/cli-bundle/chunks/{create-IFA26O2I.js → create-5433DP3G.js} +2 -2
- package/dist/cli-bundle/chunks/{create-JVXYHYH4.js → create-VWLWS34Z.js} +2 -2
- package/dist/cli-bundle/chunks/{docs-5WMBVQT2.js → docs-I3BAF5WH.js} +4 -4
- package/dist/cli-bundle/chunks/docs-I3BAF5WH.js.map +1 -0
- package/dist/cli-bundle/chunks/{docs-MB53UJAJ.js → docs-MXLGZUIT.js} +3 -3
- package/dist/cli-bundle/chunks/docs-MXLGZUIT.js.map +7 -0
- package/dist/cli-bundle/chunks/{files-GVMNVLCB.js → files-FYP3MDPX.js} +3 -3
- package/dist/cli-bundle/chunks/files-FYP3MDPX.js.map +7 -0
- package/dist/cli-bundle/chunks/{files-DLB5LJEP.js → files-GUXUM2MB.js} +4 -4
- package/dist/cli-bundle/chunks/files-GUXUM2MB.js.map +1 -0
- package/dist/cli-bundle/chunks/{gc-2WEPW6D6.js → gc-FENB2ESG.js} +12 -174
- package/dist/cli-bundle/chunks/gc-FENB2ESG.js.map +1 -0
- package/dist/cli-bundle/chunks/{gc-4Z3IKHAZ.js → gc-KGQG66SA.js} +10 -179
- package/dist/cli-bundle/chunks/gc-KGQG66SA.js.map +7 -0
- package/dist/cli-bundle/chunks/{health-YO5LRWN4.js → health-7MTXAVR2.js} +71 -4
- package/dist/cli-bundle/chunks/health-7MTXAVR2.js.map +7 -0
- package/dist/cli-bundle/chunks/{health-4ZYB3IYQ.js → health-E4D7KGHD.js} +72 -5
- package/dist/cli-bundle/chunks/health-E4D7KGHD.js.map +1 -0
- package/dist/cli-bundle/chunks/{history-repair-KVPFJKOS.js → history-repair-OSQOKJ3E.js} +61 -3
- package/dist/cli-bundle/chunks/history-repair-OSQOKJ3E.js.map +7 -0
- package/dist/cli-bundle/chunks/{history-repair-RUGKD3YR.js → history-repair-SBK7P34V.js} +62 -4
- package/dist/cli-bundle/chunks/history-repair-SBK7P34V.js.map +1 -0
- package/dist/cli-bundle/chunks/{plan-VNUG3WZZ.js → plan-2YTQYWGM.js} +52 -12
- package/dist/cli-bundle/chunks/plan-2YTQYWGM.js.map +1 -0
- package/dist/cli-bundle/chunks/{plan-FQLMJRLZ.js → plan-7IVSICR6.js} +51 -11
- package/dist/cli-bundle/chunks/plan-7IVSICR6.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-list-query-VHDXWEPP.js → register-list-query-4UPMHONX.js} +3 -3
- package/dist/cli-bundle/chunks/{register-list-query-NPE3ECJQ.js → register-list-query-7VOW2C3W.js} +3 -3
- package/dist/cli-bundle/chunks/{register-mutation-EAYNLGOS.js → register-mutation-FARSGYRD.js} +43 -26
- package/dist/cli-bundle/chunks/{register-mutation-EAYNLGOS.js.map → register-mutation-FARSGYRD.js.map} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-DG53FCBV.js → register-mutation-LJDNVREU.js} +44 -27
- package/dist/cli-bundle/chunks/{register-mutation-DG53FCBV.js.map → register-mutation-LJDNVREU.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-operations-AM6KTWB6.js → register-operations-FFTYAL42.js} +17 -13
- package/dist/cli-bundle/chunks/register-operations-FFTYAL42.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-operations-FWFE64JG.js → register-operations-HCJKDUA6.js} +16 -12
- package/dist/cli-bundle/chunks/{register-operations-FWFE64JG.js.map → register-operations-HCJKDUA6.js.map} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-IKX5524L.js → register-setup-6AVIUOCC.js} +19 -19
- package/dist/cli-bundle/chunks/register-setup-6AVIUOCC.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-setup-G4QYI3RX.js → register-setup-KVNLO5OJ.js} +18 -18
- package/dist/cli-bundle/chunks/register-setup-KVNLO5OJ.js.map +7 -0
- package/dist/cli-bundle/chunks/{update-2EVXOC7V.js → update-36JM7YZT.js} +3 -3
- package/dist/cli-bundle/chunks/{update-5A2B6QYB.js → update-I246PCLO.js} +3 -3
- package/dist/cli-bundle/chunks/{update-many-V4LA3C4H.js → update-many-F4IKDWZB.js} +3 -3
- package/dist/cli-bundle/chunks/{update-many-TUGU5YXQ.js → update-many-NTWZ5YT3.js} +3 -3
- package/dist/cli-bundle/chunks/{validate-EQTT6WVX.js → validate-46KCRHL7.js} +448 -36
- package/dist/cli-bundle/chunks/validate-46KCRHL7.js.map +1 -0
- package/dist/cli-bundle/chunks/{validate-XN4I4DPL.js → validate-CRFMPTYD.js} +468 -35
- package/dist/cli-bundle/chunks/validate-CRFMPTYD.js.map +7 -0
- package/dist/cli-bundle/main.js +24 -10
- package/dist/cli-bundle/main.js.map +2 -2
- package/dist/core/diagnostics/remediation.js +19 -6
- package/dist/core/diagnostics/remediation.js.map +1 -1
- package/dist/core/lock/lock-gc.d.ts +31 -0
- package/dist/core/lock/lock-gc.js +120 -62
- package/dist/core/lock/lock-gc.js.map +1 -1
- package/dist/core/telemetry/consent.js +18 -3
- package/dist/core/telemetry/consent.js.map +1 -1
- package/dist/core/validate/fix-planning.d.ts +130 -0
- package/dist/core/validate/fix-planning.js +202 -0
- package/dist/core/validate/fix-planning.js.map +1 -0
- package/dist/core/validate/missing-by-type.d.ts +21 -0
- package/dist/core/validate/missing-by-type.js +39 -0
- package/dist/core/validate/missing-by-type.js.map +1 -0
- package/dist/core/validate/stale-file-classification.d.ts +41 -0
- package/dist/core/validate/stale-file-classification.js +73 -0
- package/dist/core/validate/stale-file-classification.js.map +1 -0
- package/dist/mcp/server.js +41 -8
- package/dist/mcp/server.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +38 -2
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
- package/dist/sdk/cli-contracts.d.ts +6 -1
- package/dist/sdk/cli-contracts.js +74 -7
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/docs/AGENT_GUIDE.md +6 -1
- package/docs/COMMANDS.md +23 -1
- package/package.json +1 -1
- package/dist/cli-bundle/chunks/chunk-E5DUIJA4.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-FXRU333M.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-LCSCXBGT.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-P2PSODAQ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-PSD7F7DX.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-UOO6BYIA.js.map +0 -1
- package/dist/cli-bundle/chunks/docs-5WMBVQT2.js.map +0 -1
- package/dist/cli-bundle/chunks/docs-MB53UJAJ.js.map +0 -7
- package/dist/cli-bundle/chunks/files-DLB5LJEP.js.map +0 -1
- package/dist/cli-bundle/chunks/files-GVMNVLCB.js.map +0 -7
- package/dist/cli-bundle/chunks/gc-2WEPW6D6.js.map +0 -1
- package/dist/cli-bundle/chunks/gc-4Z3IKHAZ.js.map +0 -7
- package/dist/cli-bundle/chunks/health-4ZYB3IYQ.js.map +0 -1
- package/dist/cli-bundle/chunks/health-YO5LRWN4.js.map +0 -7
- package/dist/cli-bundle/chunks/history-repair-KVPFJKOS.js.map +0 -7
- package/dist/cli-bundle/chunks/history-repair-RUGKD3YR.js.map +0 -1
- package/dist/cli-bundle/chunks/plan-FQLMJRLZ.js.map +0 -7
- package/dist/cli-bundle/chunks/plan-VNUG3WZZ.js.map +0 -1
- package/dist/cli-bundle/chunks/register-operations-AM6KTWB6.js.map +0 -1
- package/dist/cli-bundle/chunks/register-setup-G4QYI3RX.js.map +0 -7
- package/dist/cli-bundle/chunks/register-setup-IKX5524L.js.map +0 -1
- package/dist/cli-bundle/chunks/validate-EQTT6WVX.js.map +0 -1
- package/dist/cli-bundle/chunks/validate-XN4I4DPL.js.map +0 -7
- /package/dist/cli-bundle/chunks/{chunk-B65UUCGQ.js.map → chunk-37CYVF73.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3SLOMKCJ.js.map → chunk-L5EPZQIC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7RIT3OCD.js.map → chunk-SO55HRA5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IH4MBKK7.js.map → chunk-XWMF3POR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{contracts-3NKWYKKU.js.map → contracts-2G66IGIA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{contracts-MIXBWJIB.js.map → contracts-PJCHYSO5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-IFA26O2I.js.map → create-5433DP3G.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-JVXYHYH4.js.map → create-VWLWS34Z.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-list-query-VHDXWEPP.js.map → register-list-query-4UPMHONX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-list-query-NPE3ECJQ.js.map → register-list-query-7VOW2C3W.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-2EVXOC7V.js.map → update-36JM7YZT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-5A2B6QYB.js.map → update-I246PCLO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-V4LA3C4H.js.map → update-many-F4IKDWZB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-TUGU5YXQ.js.map → update-many-NTWZ5YT3.js.map} +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
buildRemediationCommands
|
|
3
|
-
|
|
4
|
-
} from "./chunk-LCSCXBGT.js";
|
|
2
|
+
buildRemediationCommands
|
|
3
|
+
} from "./chunk-R4VWYWRN.js";
|
|
5
4
|
import {
|
|
6
5
|
extractReferencedPmItemIdsFromCommand
|
|
7
6
|
} from "./chunk-HHHJ2GI3.js";
|
|
7
|
+
import {
|
|
8
|
+
scanHistoryDrift
|
|
9
|
+
} from "./chunk-R2OUQVBK.js";
|
|
8
10
|
import "./chunk-XMBI6TNW.js";
|
|
9
11
|
import "./chunk-SXKNJPQ7.js";
|
|
10
12
|
import "./chunk-TNAP7EJX.js";
|
|
@@ -47,10 +49,230 @@ import { realpathSync } from "node:fs";
|
|
|
47
49
|
import { execFile } from "node:child_process";
|
|
48
50
|
import path from "node:path";
|
|
49
51
|
import { promisify } from "node:util";
|
|
52
|
+
|
|
53
|
+
// dist/core/validate/fix-planning.js
|
|
54
|
+
!(function() {
|
|
55
|
+
try {
|
|
56
|
+
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
|
|
57
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "7163fbbf-1a9c-52e0-a1d5-6034abefc50f");
|
|
58
|
+
} catch (e2) {
|
|
59
|
+
}
|
|
60
|
+
})();
|
|
61
|
+
var DEFAULT_GRANTED_FIX_SCOPES = ["metadata", "resolution"];
|
|
62
|
+
var SUPPORTED_FIX_SCOPES = ["metadata", "resolution", "lifecycle"];
|
|
63
|
+
var DEFAULT_RESOLUTION_BACKFILL_VALUE = "completed";
|
|
64
|
+
function quoteForCommand(value) {
|
|
65
|
+
return `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
66
|
+
}
|
|
67
|
+
function toMeaningfulValue(value) {
|
|
68
|
+
const trimmed = value?.trim();
|
|
69
|
+
return trimmed !== void 0 && trimmed.length > 0 ? trimmed : void 0;
|
|
70
|
+
}
|
|
71
|
+
function planResolutionBackfillFixes(rows) {
|
|
72
|
+
const fixes = [];
|
|
73
|
+
for (const row of rows) {
|
|
74
|
+
if (!row.missing_fields.includes("resolution")) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const value = toMeaningfulValue(row.close_reason) ?? DEFAULT_RESOLUTION_BACKFILL_VALUE;
|
|
78
|
+
fixes.push({
|
|
79
|
+
item_id: row.id,
|
|
80
|
+
check: "resolution",
|
|
81
|
+
field: "resolution",
|
|
82
|
+
kind: "set_resolution",
|
|
83
|
+
value,
|
|
84
|
+
command: `pm update ${row.id} --resolution ${quoteForCommand(value)}`,
|
|
85
|
+
gate: "resolution"
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return fixes;
|
|
89
|
+
}
|
|
90
|
+
function planCloseReasonBackfillFixes(rows) {
|
|
91
|
+
const fixes = [];
|
|
92
|
+
for (const row of rows) {
|
|
93
|
+
const value = toMeaningfulValue(row.resolution);
|
|
94
|
+
if (value === void 0) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
fixes.push({
|
|
98
|
+
item_id: row.id,
|
|
99
|
+
check: "metadata",
|
|
100
|
+
field: "close_reason",
|
|
101
|
+
kind: "set_close_reason",
|
|
102
|
+
value,
|
|
103
|
+
command: `pm update ${row.id} --close-reason ${quoteForCommand(value)}`,
|
|
104
|
+
gate: "metadata"
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return fixes;
|
|
108
|
+
}
|
|
109
|
+
function planTerminalParentFixes(rows) {
|
|
110
|
+
return rows.map((row) => {
|
|
111
|
+
if (row.grandparent_id !== void 0 && row.grandparent_active === true) {
|
|
112
|
+
return {
|
|
113
|
+
item_id: row.id,
|
|
114
|
+
check: "lifecycle",
|
|
115
|
+
field: "parent",
|
|
116
|
+
kind: "reparent",
|
|
117
|
+
parent_id: row.grandparent_id,
|
|
118
|
+
command: `pm update ${row.id} --parent ${row.grandparent_id}`,
|
|
119
|
+
gate: "lifecycle"
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
item_id: row.id,
|
|
124
|
+
check: "lifecycle",
|
|
125
|
+
field: "parent",
|
|
126
|
+
kind: "unset_parent",
|
|
127
|
+
command: `pm update ${row.id} --unset parent`,
|
|
128
|
+
gate: "lifecycle"
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function planStaleLinkPruneFixes(rows) {
|
|
133
|
+
const fixes = [];
|
|
134
|
+
for (const row of rows) {
|
|
135
|
+
if (row.classification !== "deleted") {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const noun = row.link_kind === "files" ? "files" : "docs";
|
|
139
|
+
fixes.push({
|
|
140
|
+
item_id: row.item_id,
|
|
141
|
+
check: "files",
|
|
142
|
+
field: row.link_kind,
|
|
143
|
+
kind: row.link_kind === "files" ? "prune_file_link" : "prune_doc_link",
|
|
144
|
+
path: row.path,
|
|
145
|
+
command: `pm ${noun} ${row.item_id} --remove ${quoteForCommand(row.path)}`
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return fixes;
|
|
149
|
+
}
|
|
150
|
+
function resolveGrantedFixScopes(rawScopes) {
|
|
151
|
+
const tokens = (rawScopes ?? []).flatMap((raw) => raw.split(",")).map((raw) => raw.trim()).filter((raw) => raw.length > 0);
|
|
152
|
+
if (tokens.length === 0) {
|
|
153
|
+
if (rawScopes !== void 0 && rawScopes.length > 0) {
|
|
154
|
+
throw new PmCliError(`--fix-scope values must not be empty. Supported values: ${SUPPORTED_FIX_SCOPES.join(", ")}.`, EXIT_CODE.USAGE);
|
|
155
|
+
}
|
|
156
|
+
return new Set(DEFAULT_GRANTED_FIX_SCOPES);
|
|
157
|
+
}
|
|
158
|
+
const granted = /* @__PURE__ */ new Set();
|
|
159
|
+
for (const raw of tokens) {
|
|
160
|
+
const normalized = raw.toLowerCase().replaceAll("-", "_");
|
|
161
|
+
if (SUPPORTED_FIX_SCOPES.includes(normalized)) {
|
|
162
|
+
granted.add(normalized);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
throw new PmCliError(`Unknown --fix-scope value "${raw}". Supported values: ${SUPPORTED_FIX_SCOPES.join(", ")}.`, EXIT_CODE.USAGE);
|
|
166
|
+
}
|
|
167
|
+
return granted;
|
|
168
|
+
}
|
|
169
|
+
function partitionFixesByGrant(fixes, granted) {
|
|
170
|
+
const applicable = [];
|
|
171
|
+
const gated = [];
|
|
172
|
+
for (const fix of fixes) {
|
|
173
|
+
if (fix.gate !== void 0 && !granted.has(fix.gate)) {
|
|
174
|
+
gated.push(fix);
|
|
175
|
+
} else {
|
|
176
|
+
applicable.push(fix);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return { applicable, gated };
|
|
180
|
+
}
|
|
181
|
+
function toFixOutputRow(fix) {
|
|
182
|
+
return {
|
|
183
|
+
item_id: fix.item_id,
|
|
184
|
+
check: fix.check,
|
|
185
|
+
field: fix.field,
|
|
186
|
+
command: fix.command,
|
|
187
|
+
...fix.gate !== void 0 ? { gate: fix.gate } : {}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// dist/core/validate/missing-by-type.js
|
|
192
|
+
!(function() {
|
|
193
|
+
try {
|
|
194
|
+
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
|
|
195
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "16988d98-5a10-5e0a-952c-0a6289ab5935");
|
|
196
|
+
} catch (e2) {
|
|
197
|
+
}
|
|
198
|
+
})();
|
|
199
|
+
function buildMissingByTypeCounts(occurrences) {
|
|
200
|
+
const countsByType = /* @__PURE__ */ new Map();
|
|
201
|
+
for (const occurrence of occurrences) {
|
|
202
|
+
let fieldCounts = countsByType.get(occurrence.item_type);
|
|
203
|
+
if (!fieldCounts) {
|
|
204
|
+
fieldCounts = /* @__PURE__ */ new Map();
|
|
205
|
+
countsByType.set(occurrence.item_type, fieldCounts);
|
|
206
|
+
}
|
|
207
|
+
fieldCounts.set(occurrence.field, (fieldCounts.get(occurrence.field) ?? 0) + 1);
|
|
208
|
+
}
|
|
209
|
+
const result = {};
|
|
210
|
+
for (const type of [...countsByType.keys()].sort((left, right) => left.localeCompare(right))) {
|
|
211
|
+
const fieldCounts = countsByType.get(type);
|
|
212
|
+
const fields = {};
|
|
213
|
+
for (const field of [...fieldCounts.keys()].sort((left, right) => left.localeCompare(right))) {
|
|
214
|
+
fields[field] = fieldCounts.get(field);
|
|
215
|
+
}
|
|
216
|
+
result[type] = fields;
|
|
217
|
+
}
|
|
218
|
+
return result;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// dist/core/validate/stale-file-classification.js
|
|
222
|
+
!(function() {
|
|
223
|
+
try {
|
|
224
|
+
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
|
|
225
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "2df68560-32a7-5762-9470-cf82e978a90d");
|
|
226
|
+
} catch (e2) {
|
|
227
|
+
}
|
|
228
|
+
})();
|
|
229
|
+
var DEFAULT_STALE_PATH_CANDIDATE_LIMIT = 3;
|
|
230
|
+
function basenameOf(relativePath) {
|
|
231
|
+
const lastSlash = Math.max(relativePath.lastIndexOf("/"), relativePath.lastIndexOf("\\"));
|
|
232
|
+
return lastSlash === -1 ? relativePath : relativePath.slice(lastSlash + 1);
|
|
233
|
+
}
|
|
234
|
+
function classifyStaleLinkedPaths(stalePaths, candidateFiles, candidateLimit = DEFAULT_STALE_PATH_CANDIDATE_LIMIT) {
|
|
235
|
+
const limit = Number.isFinite(candidateLimit) && candidateLimit >= 1 ? Math.floor(candidateLimit) : DEFAULT_STALE_PATH_CANDIDATE_LIMIT;
|
|
236
|
+
const candidatesByBasename = /* @__PURE__ */ new Map();
|
|
237
|
+
for (const candidate of candidateFiles) {
|
|
238
|
+
const basename = basenameOf(candidate);
|
|
239
|
+
if (basename.length === 0) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const bucket = candidatesByBasename.get(basename);
|
|
243
|
+
if (bucket) {
|
|
244
|
+
bucket.push(candidate);
|
|
245
|
+
} else {
|
|
246
|
+
candidatesByBasename.set(basename, [candidate]);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return stalePaths.map((stalePath) => {
|
|
250
|
+
const matches = (candidatesByBasename.get(basenameOf(stalePath)) ?? []).filter((candidate) => candidate !== stalePath).sort((left, right) => left.localeCompare(right));
|
|
251
|
+
if (matches.length === 0) {
|
|
252
|
+
return {
|
|
253
|
+
path: stalePath,
|
|
254
|
+
classification: "deleted",
|
|
255
|
+
candidates: [],
|
|
256
|
+
candidates_truncated: false
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
path: stalePath,
|
|
261
|
+
classification: "moved",
|
|
262
|
+
candidates: matches.slice(0, limit),
|
|
263
|
+
candidates_truncated: matches.length > limit
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
function summarizeStaleLinkedPathClassifications(classified) {
|
|
268
|
+
return classified.map((entry) => entry.classification === "moved" ? `${entry.path}:moved:${entry.candidates[0]}` : `${entry.path}:deleted`);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// dist/cli/commands/validate.js
|
|
50
272
|
!(function() {
|
|
51
273
|
try {
|
|
52
274
|
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
|
|
53
|
-
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "
|
|
275
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "b92552cc-f7d2-5100-a23c-bb53d8445bc6");
|
|
54
276
|
} catch (e2) {
|
|
55
277
|
}
|
|
56
278
|
})();
|
|
@@ -525,17 +747,32 @@ function resolveRequestedChecks(options) {
|
|
|
525
747
|
requested.add("command_references");
|
|
526
748
|
}
|
|
527
749
|
if (requested.size === 0) {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
750
|
+
if (options.autoFix) {
|
|
751
|
+
requested.add("metadata");
|
|
752
|
+
requested.add("resolution");
|
|
753
|
+
requested.add("lifecycle");
|
|
754
|
+
}
|
|
755
|
+
if (options.pruneMissing) {
|
|
756
|
+
requested.add("files");
|
|
757
|
+
}
|
|
758
|
+
if (requested.size === 0) {
|
|
759
|
+
requested.add("metadata");
|
|
760
|
+
requested.add("resolution");
|
|
761
|
+
requested.add("lifecycle");
|
|
762
|
+
requested.add("files");
|
|
763
|
+
requested.add("command_references");
|
|
764
|
+
requested.add("history_drift");
|
|
765
|
+
}
|
|
766
|
+
return requested;
|
|
767
|
+
}
|
|
768
|
+
if (options.pruneMissing) {
|
|
531
769
|
requested.add("files");
|
|
532
|
-
requested.add("command_references");
|
|
533
|
-
requested.add("history_drift");
|
|
534
770
|
}
|
|
535
771
|
return requested;
|
|
536
772
|
}
|
|
537
773
|
function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagnostics) {
|
|
538
774
|
const missingByField = Object.fromEntries(SUPPORTED_METADATA_REQUIRED_FIELDS.map((field) => [field, []]));
|
|
775
|
+
const itemsById = new Map(items.map((item) => [item.id, item]));
|
|
539
776
|
for (const item of items) {
|
|
540
777
|
for (const field of SUPPORTED_METADATA_REQUIRED_FIELDS) {
|
|
541
778
|
if (!isMetadataFieldMissing(item, field, statusRegistry)) {
|
|
@@ -560,6 +797,14 @@ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagno
|
|
|
560
797
|
counts[countKey] = value;
|
|
561
798
|
}
|
|
562
799
|
}
|
|
800
|
+
const missingFieldOccurrences = [];
|
|
801
|
+
for (const field of metadataPolicy.required_fields) {
|
|
802
|
+
for (const itemId of missingByField[field] ?? []) {
|
|
803
|
+
const itemType = itemsById.get(itemId)?.type;
|
|
804
|
+
missingFieldOccurrences.push({ item_type: typeof itemType === "string" && itemType.length > 0 ? itemType : "Unknown", field });
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
const missingByType = buildMissingByTypeCounts(missingFieldOccurrences);
|
|
563
808
|
const details = {
|
|
564
809
|
checked_items: items.length,
|
|
565
810
|
metadata_profile: metadataPolicy.profile,
|
|
@@ -567,7 +812,8 @@ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagno
|
|
|
567
812
|
metadata_profile_fallback_to_core: metadataPolicy.fallback_to_core,
|
|
568
813
|
required_fields: [...metadataPolicy.required_fields],
|
|
569
814
|
supported_required_fields: [...SUPPORTED_METADATA_REQUIRED_FIELDS],
|
|
570
|
-
counts
|
|
815
|
+
counts,
|
|
816
|
+
missing_by_type: missingByType
|
|
571
817
|
};
|
|
572
818
|
if (metadataPolicy.configured_custom_fields.length > 0) {
|
|
573
819
|
details.configured_custom_required_fields = [...metadataPolicy.configured_custom_fields];
|
|
@@ -586,13 +832,18 @@ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagno
|
|
|
586
832
|
details[idsKey] = summarized.values;
|
|
587
833
|
details[truncatedKey] = summarized.truncated;
|
|
588
834
|
}
|
|
835
|
+
const closeReasonBackfillRows = metadataPolicy.required_fields.includes("close_reason") ? (missingByField.close_reason ?? []).map((itemId) => ({
|
|
836
|
+
id: itemId,
|
|
837
|
+
resolution: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.resolution)
|
|
838
|
+
})) : [];
|
|
589
839
|
return {
|
|
590
840
|
check: {
|
|
591
841
|
name: "metadata",
|
|
592
842
|
status: warningTokens.length === 0 ? "ok" : "warn",
|
|
593
843
|
details
|
|
594
844
|
},
|
|
595
|
-
warnings: warningTokens
|
|
845
|
+
warnings: warningTokens,
|
|
846
|
+
closeReasonBackfillRows
|
|
596
847
|
};
|
|
597
848
|
}
|
|
598
849
|
function buildResolutionCheck(items, statusRegistry, verboseDiagnostics) {
|
|
@@ -600,6 +851,7 @@ function buildResolutionCheck(items, statusRegistry, verboseDiagnostics) {
|
|
|
600
851
|
terminalDoneStatuses.add(statusRegistry.close_status);
|
|
601
852
|
const closedItems = items.filter((item) => terminalDoneStatuses.has(normalizeStatusForRegistry(item.status, statusRegistry)));
|
|
602
853
|
const missingResolutionRows = [];
|
|
854
|
+
const resolutionBackfillRows = [];
|
|
603
855
|
for (const item of closedItems) {
|
|
604
856
|
const missingFields = RESOLUTION_FIELD_KEYS.filter((field) => !toNonEmptyStringOrUndefined(item[field]));
|
|
605
857
|
if (missingFields.length === 0) {
|
|
@@ -609,6 +861,11 @@ function buildResolutionCheck(items, statusRegistry, verboseDiagnostics) {
|
|
|
609
861
|
id: item.id,
|
|
610
862
|
missing_fields: missingFields
|
|
611
863
|
});
|
|
864
|
+
resolutionBackfillRows.push({
|
|
865
|
+
id: item.id,
|
|
866
|
+
missing_fields: missingFields,
|
|
867
|
+
close_reason: toNonEmptyStringOrUndefined(item.close_reason)
|
|
868
|
+
});
|
|
612
869
|
}
|
|
613
870
|
const warnings = missingResolutionRows.length > 0 ? [`validate_resolution_missing_fields:${missingResolutionRows.length}`] : [];
|
|
614
871
|
const diagnosticLimit = verboseDiagnostics ? Number.POSITIVE_INFINITY : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
|
|
@@ -628,7 +885,8 @@ function buildResolutionCheck(items, statusRegistry, verboseDiagnostics) {
|
|
|
628
885
|
missing_resolution_remediation_hints_truncated: summarizedHints.truncated
|
|
629
886
|
}
|
|
630
887
|
},
|
|
631
|
-
warnings
|
|
888
|
+
warnings,
|
|
889
|
+
resolutionBackfillRows
|
|
632
890
|
};
|
|
633
891
|
}
|
|
634
892
|
function buildLifecycleDependencyGraph(activeItems) {
|
|
@@ -749,6 +1007,7 @@ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverit
|
|
|
749
1007
|
const activeItems = items.filter((item) => !isTerminalStatus(item.status, statusRegistry));
|
|
750
1008
|
const closureLikeRows = [];
|
|
751
1009
|
const terminalParentRows = [];
|
|
1010
|
+
const terminalParentFixRows = [];
|
|
752
1011
|
const staleBlockerRows = [];
|
|
753
1012
|
for (const item of activeItems) {
|
|
754
1013
|
const closureLikeFields = Object.entries(lifecyclePatternPolicy.closure_like_metadata_field_patterns).filter(([field, patterns]) => {
|
|
@@ -774,6 +1033,14 @@ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverit
|
|
|
774
1033
|
parent_id: parent.id,
|
|
775
1034
|
parent_status: parent.status
|
|
776
1035
|
});
|
|
1036
|
+
const grandparentId = toMeaningfulString(parent.parent);
|
|
1037
|
+
const grandparent = grandparentId ? itemsById.get(grandparentId) : void 0;
|
|
1038
|
+
terminalParentFixRows.push({
|
|
1039
|
+
id: item.id,
|
|
1040
|
+
parent_id: parent.id,
|
|
1041
|
+
grandparent_id: grandparent?.id,
|
|
1042
|
+
grandparent_active: grandparent !== void 0 && !isTerminalStatus(grandparent.status, statusRegistry)
|
|
1043
|
+
});
|
|
777
1044
|
}
|
|
778
1045
|
}
|
|
779
1046
|
if (includeStaleBlockers) {
|
|
@@ -811,6 +1078,7 @@ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverit
|
|
|
811
1078
|
}
|
|
812
1079
|
closureLikeRows.sort((left, right) => left.id.localeCompare(right.id));
|
|
813
1080
|
terminalParentRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
|
|
1081
|
+
terminalParentFixRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
|
|
814
1082
|
staleBlockerRows.sort((left, right) => left.id.localeCompare(right.id));
|
|
815
1083
|
const dependencyCycleDiagnostics = detectLifecycleDependencyCycles(activeItems);
|
|
816
1084
|
const warnings = [];
|
|
@@ -867,31 +1135,43 @@ function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverit
|
|
|
867
1135
|
closure_like_actual_result_pattern_source: lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.actual_result
|
|
868
1136
|
}
|
|
869
1137
|
},
|
|
870
|
-
warnings
|
|
1138
|
+
warnings,
|
|
1139
|
+
terminalParentFixRows
|
|
871
1140
|
};
|
|
872
1141
|
}
|
|
873
1142
|
async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, includePmInternals, verboseFileLists) {
|
|
874
1143
|
const linkedProjectPaths = /* @__PURE__ */ new Set();
|
|
875
1144
|
const missingLinkedPaths = [];
|
|
1145
|
+
const staleLinkRows = [];
|
|
876
1146
|
for (const item of items) {
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
const
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
1147
|
+
const linkedArtifactGroups = [
|
|
1148
|
+
{ link_kind: "files", artifacts: item.files ?? [] },
|
|
1149
|
+
{ link_kind: "docs", artifacts: item.docs ?? [] }
|
|
1150
|
+
];
|
|
1151
|
+
for (const group of linkedArtifactGroups) {
|
|
1152
|
+
for (const artifact of group.artifacts) {
|
|
1153
|
+
if (artifact.scope !== "project") {
|
|
1154
|
+
continue;
|
|
1155
|
+
}
|
|
1156
|
+
const normalizedPath = normalizeRelativePath(artifact.path);
|
|
1157
|
+
if (normalizedPath.length === 0) {
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
linkedProjectPaths.add(normalizedPath);
|
|
1161
|
+
const absolutePath = path.isAbsolute(artifact.path) ? artifact.path : path.resolve(workspaceRoot, artifact.path);
|
|
1162
|
+
let missing = false;
|
|
1163
|
+
try {
|
|
1164
|
+
const stats = await fs.stat(absolutePath);
|
|
1165
|
+
if (!stats.isFile()) {
|
|
1166
|
+
missing = true;
|
|
1167
|
+
}
|
|
1168
|
+
} catch {
|
|
1169
|
+
missing = true;
|
|
1170
|
+
}
|
|
1171
|
+
if (missing) {
|
|
891
1172
|
missingLinkedPaths.push(normalizedPath);
|
|
1173
|
+
staleLinkRows.push({ item_id: item.id, path: normalizedPath, link_kind: group.link_kind });
|
|
892
1174
|
}
|
|
893
|
-
} catch {
|
|
894
|
-
missingLinkedPaths.push(normalizedPath);
|
|
895
1175
|
}
|
|
896
1176
|
}
|
|
897
1177
|
}
|
|
@@ -915,6 +1195,13 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
|
|
|
915
1195
|
};
|
|
916
1196
|
}
|
|
917
1197
|
const orphanedFiles = candidateFiles.filter((candidate) => !linkedProjectPaths.has(candidate));
|
|
1198
|
+
const classifiedStalePaths = classifyStaleLinkedPaths(uniqueMissingLinkedPaths, candidateFiles);
|
|
1199
|
+
const classificationByPath = new Map(classifiedStalePaths.map((entry) => [entry.path, entry.classification]));
|
|
1200
|
+
const movedStalePathCount = classifiedStalePaths.filter((entry) => entry.classification === "moved").length;
|
|
1201
|
+
const staleLinkPruneRows = staleLinkRows.map((row) => ({
|
|
1202
|
+
...row,
|
|
1203
|
+
classification: classificationByPath.get(row.path) ?? "deleted"
|
|
1204
|
+
})).sort((left, right) => left.item_id.localeCompare(right.item_id) || left.path.localeCompare(right.path) || left.link_kind.localeCompare(right.link_kind));
|
|
918
1205
|
const warnings = [];
|
|
919
1206
|
if (strictModeForcesPmInternals) {
|
|
920
1207
|
warnings.push("validate_files_tracked_all_strict_forces_pm_internals");
|
|
@@ -927,6 +1214,7 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
|
|
|
927
1214
|
}
|
|
928
1215
|
const summarizedMissing = summarizeFileList(uniqueMissingLinkedPaths, verboseFileLists);
|
|
929
1216
|
const summarizedOrphaned = summarizeFileList(orphanedFiles, verboseFileLists);
|
|
1217
|
+
const summarizedClassifications = summarizeFileList(summarizeStaleLinkedPathClassifications(classifiedStalePaths), verboseFileLists);
|
|
930
1218
|
return {
|
|
931
1219
|
check: {
|
|
932
1220
|
name: "files",
|
|
@@ -957,13 +1245,18 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
|
|
|
957
1245
|
missing_linked_paths_total: summarizedMissing.total,
|
|
958
1246
|
missing_linked_paths: summarizedMissing.values,
|
|
959
1247
|
missing_linked_paths_truncated: summarizedMissing.truncated,
|
|
1248
|
+
missing_linked_paths_moved_count: movedStalePathCount,
|
|
1249
|
+
missing_linked_paths_deleted_count: uniqueMissingLinkedPaths.length - movedStalePathCount,
|
|
1250
|
+
missing_linked_path_classifications: summarizedClassifications.values,
|
|
1251
|
+
missing_linked_path_classifications_truncated: summarizedClassifications.truncated,
|
|
960
1252
|
orphaned_paths_count: orphanedFiles.length,
|
|
961
1253
|
orphaned_paths_total: summarizedOrphaned.total,
|
|
962
1254
|
orphaned_paths: summarizedOrphaned.values,
|
|
963
1255
|
orphaned_paths_truncated: summarizedOrphaned.truncated
|
|
964
1256
|
}
|
|
965
1257
|
},
|
|
966
|
-
warnings
|
|
1258
|
+
warnings,
|
|
1259
|
+
staleLinkPruneRows
|
|
967
1260
|
};
|
|
968
1261
|
}
|
|
969
1262
|
async function buildHistoryDriftCheck(pmRoot, items, verboseDiagnostics) {
|
|
@@ -1062,7 +1355,93 @@ function buildCommandReferencesCheck(items, idPrefix, verboseDiagnostics) {
|
|
|
1062
1355
|
warnings
|
|
1063
1356
|
};
|
|
1064
1357
|
}
|
|
1358
|
+
var VALIDATE_AUTO_FIX_MESSAGE = "pm validate auto-fix";
|
|
1359
|
+
async function applyValidateFix(fix, global2) {
|
|
1360
|
+
switch (fix.kind) {
|
|
1361
|
+
case "set_resolution":
|
|
1362
|
+
case "set_close_reason":
|
|
1363
|
+
case "reparent":
|
|
1364
|
+
case "unset_parent": {
|
|
1365
|
+
const { runUpdate } = await import("./update-36JM7YZT.js");
|
|
1366
|
+
const updateOptions = { message: VALIDATE_AUTO_FIX_MESSAGE };
|
|
1367
|
+
if (fix.kind === "set_resolution") {
|
|
1368
|
+
updateOptions.resolution = fix.value;
|
|
1369
|
+
} else if (fix.kind === "set_close_reason") {
|
|
1370
|
+
updateOptions.closeReason = fix.value;
|
|
1371
|
+
} else if (fix.kind === "reparent") {
|
|
1372
|
+
updateOptions.parent = fix.parent_id;
|
|
1373
|
+
} else {
|
|
1374
|
+
updateOptions.unset = ["parent"];
|
|
1375
|
+
}
|
|
1376
|
+
await runUpdate(fix.item_id, updateOptions, global2);
|
|
1377
|
+
return;
|
|
1378
|
+
}
|
|
1379
|
+
case "prune_file_link": {
|
|
1380
|
+
throw new Error(`Unsupported non-batched fix kind: ${fix.kind}`);
|
|
1381
|
+
}
|
|
1382
|
+
case "prune_doc_link": {
|
|
1383
|
+
throw new Error(`Unsupported non-batched fix kind: ${fix.kind}`);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
function pruneBatchKey(fix) {
|
|
1388
|
+
if (fix.kind !== "prune_file_link" && fix.kind !== "prune_doc_link") {
|
|
1389
|
+
return null;
|
|
1390
|
+
}
|
|
1391
|
+
return `${fix.kind}:${fix.item_id}`;
|
|
1392
|
+
}
|
|
1393
|
+
async function applyValidateFixes(applicable, global2) {
|
|
1394
|
+
const applied = [];
|
|
1395
|
+
const failed = [];
|
|
1396
|
+
const pruneBatches = /* @__PURE__ */ new Map();
|
|
1397
|
+
for (const fix of applicable) {
|
|
1398
|
+
const batchKey = pruneBatchKey(fix);
|
|
1399
|
+
if (batchKey === null) {
|
|
1400
|
+
try {
|
|
1401
|
+
await applyValidateFix(fix, global2);
|
|
1402
|
+
applied.push(fix);
|
|
1403
|
+
} catch (error) {
|
|
1404
|
+
failed.push({ fix, error });
|
|
1405
|
+
}
|
|
1406
|
+
continue;
|
|
1407
|
+
}
|
|
1408
|
+
const existing = pruneBatches.get(batchKey);
|
|
1409
|
+
if (existing) {
|
|
1410
|
+
existing.push(fix);
|
|
1411
|
+
} else {
|
|
1412
|
+
pruneBatches.set(batchKey, [fix]);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
for (const batch of pruneBatches.values()) {
|
|
1416
|
+
const first = batch[0];
|
|
1417
|
+
if (!first) {
|
|
1418
|
+
continue;
|
|
1419
|
+
}
|
|
1420
|
+
const remove = batch.map((fix) => fix.path).filter((value) => typeof value === "string" && value.length > 0);
|
|
1421
|
+
try {
|
|
1422
|
+
if (first.kind === "prune_file_link") {
|
|
1423
|
+
const { runFiles } = await import("./files-FYP3MDPX.js");
|
|
1424
|
+
await runFiles(first.item_id, { remove, message: VALIDATE_AUTO_FIX_MESSAGE }, global2);
|
|
1425
|
+
} else {
|
|
1426
|
+
const { runDocs } = await import("./docs-MXLGZUIT.js");
|
|
1427
|
+
await runDocs(first.item_id, { remove, message: VALIDATE_AUTO_FIX_MESSAGE }, global2);
|
|
1428
|
+
}
|
|
1429
|
+
applied.push(...batch);
|
|
1430
|
+
} catch (error) {
|
|
1431
|
+
failed.push(...batch.map((fix) => ({ fix, error })));
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
return { applied, failed };
|
|
1435
|
+
}
|
|
1065
1436
|
async function runValidate(options, global2) {
|
|
1437
|
+
const fixesRequested = options.autoFix === true || options.pruneMissing === true;
|
|
1438
|
+
if (options.dryRun === true && !fixesRequested) {
|
|
1439
|
+
throw new PmCliError("--dry-run requires --auto-fix or --prune-missing (there is nothing to preview otherwise).", EXIT_CODE.USAGE);
|
|
1440
|
+
}
|
|
1441
|
+
if (options.fixScope !== void 0 && options.fixScope.length > 0 && options.autoFix !== true) {
|
|
1442
|
+
throw new PmCliError("--fix-scope requires --auto-fix.", EXIT_CODE.USAGE);
|
|
1443
|
+
}
|
|
1444
|
+
const grantedFixScopes = resolveGrantedFixScopes(options.fixScope);
|
|
1066
1445
|
const pmRoot = resolvePmRoot(process.cwd(), global2.path);
|
|
1067
1446
|
if (!await pathExists(getSettingsPath(pmRoot))) {
|
|
1068
1447
|
throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
|
|
@@ -1090,17 +1469,29 @@ async function runValidate(options, global2) {
|
|
|
1090
1469
|
checks.push(built.check);
|
|
1091
1470
|
warnings.push(...built.warnings);
|
|
1092
1471
|
};
|
|
1472
|
+
let closeReasonBackfillRows = [];
|
|
1473
|
+
let resolutionBackfillRows = [];
|
|
1474
|
+
let terminalParentFixRows = [];
|
|
1475
|
+
let staleLinkPruneRows = [];
|
|
1093
1476
|
if (requestedChecks.has("metadata")) {
|
|
1094
|
-
|
|
1477
|
+
const built = buildMetadataCheck(items, metadataPolicy, statusRegistry, Boolean(options.verboseDiagnostics));
|
|
1478
|
+
closeReasonBackfillRows = built.closeReasonBackfillRows;
|
|
1479
|
+
record(built);
|
|
1095
1480
|
}
|
|
1096
1481
|
if (requestedChecks.has("resolution")) {
|
|
1097
|
-
|
|
1482
|
+
const built = buildResolutionCheck(items, statusRegistry, Boolean(options.verboseDiagnostics));
|
|
1483
|
+
resolutionBackfillRows = built.resolutionBackfillRows;
|
|
1484
|
+
record(built);
|
|
1098
1485
|
}
|
|
1099
1486
|
if (requestedChecks.has("lifecycle")) {
|
|
1100
|
-
|
|
1487
|
+
const built = buildLifecycleCheck(items, Boolean(options.checkStaleBlockers), dependencyCycleSeverity, statusRegistry, lifecyclePatternPolicy, Boolean(options.verboseDiagnostics));
|
|
1488
|
+
terminalParentFixRows = built.terminalParentFixRows;
|
|
1489
|
+
record(built);
|
|
1101
1490
|
}
|
|
1102
1491
|
if (requestedChecks.has("files")) {
|
|
1103
|
-
|
|
1492
|
+
const built = await buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, Boolean(options.includePmInternals), Boolean(options.verboseFileLists));
|
|
1493
|
+
staleLinkPruneRows = built.staleLinkPruneRows;
|
|
1494
|
+
record(built);
|
|
1104
1495
|
}
|
|
1105
1496
|
if (requestedChecks.has("command_references")) {
|
|
1106
1497
|
record(buildCommandReferencesCheck(items, settings.id_prefix, Boolean(options.verboseDiagnostics)));
|
|
@@ -1108,6 +1499,47 @@ async function runValidate(options, global2) {
|
|
|
1108
1499
|
if (requestedChecks.has("history_drift")) {
|
|
1109
1500
|
record(await buildHistoryDriftCheck(pmRoot, items, Boolean(options.verboseDiagnostics)));
|
|
1110
1501
|
}
|
|
1502
|
+
let fixes;
|
|
1503
|
+
if (fixesRequested) {
|
|
1504
|
+
const planned = [];
|
|
1505
|
+
if (options.autoFix === true) {
|
|
1506
|
+
planned.push(...planCloseReasonBackfillFixes(closeReasonBackfillRows));
|
|
1507
|
+
planned.push(...planResolutionBackfillFixes(resolutionBackfillRows));
|
|
1508
|
+
planned.push(...planTerminalParentFixes(terminalParentFixRows));
|
|
1509
|
+
}
|
|
1510
|
+
if (options.pruneMissing === true) {
|
|
1511
|
+
planned.push(...planStaleLinkPruneFixes(staleLinkPruneRows));
|
|
1512
|
+
}
|
|
1513
|
+
const { applicable, gated } = partitionFixesByGrant(planned, grantedFixScopes);
|
|
1514
|
+
const dryRun = options.dryRun === true;
|
|
1515
|
+
const appliedFixRows = [];
|
|
1516
|
+
const failedFixRows = [];
|
|
1517
|
+
if (!dryRun) {
|
|
1518
|
+
const applied = await applyValidateFixes(applicable, global2);
|
|
1519
|
+
appliedFixRows.push(...applied.applied.map(toFixOutputRow));
|
|
1520
|
+
failedFixRows.push(...applied.failed.map(({ fix, error }) => ({
|
|
1521
|
+
...toFixOutputRow(fix),
|
|
1522
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1523
|
+
})));
|
|
1524
|
+
}
|
|
1525
|
+
fixes = {
|
|
1526
|
+
mode: dryRun ? "dry_run" : "apply",
|
|
1527
|
+
auto_fix: options.autoFix === true,
|
|
1528
|
+
prune_missing: options.pruneMissing === true,
|
|
1529
|
+
granted_fix_scopes: [...grantedFixScopes].sort((left, right) => left.localeCompare(right)),
|
|
1530
|
+
planned_count: planned.length,
|
|
1531
|
+
applied_count: appliedFixRows.length,
|
|
1532
|
+
gated_count: gated.length,
|
|
1533
|
+
failed_count: failedFixRows.length,
|
|
1534
|
+
planned_fixes: planned.map(toFixOutputRow),
|
|
1535
|
+
applied_fixes: appliedFixRows,
|
|
1536
|
+
gated_fixes: gated.map((fix) => ({
|
|
1537
|
+
...toFixOutputRow(fix),
|
|
1538
|
+
gate_hint: `Withheld: re-run with --fix-scope ${fix.gate} to apply.`
|
|
1539
|
+
})),
|
|
1540
|
+
failed_fixes: failedFixRows
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1111
1543
|
const normalizedWarnings = [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
|
|
1112
1544
|
const hasErrors = checks.some((check) => check.status === "error");
|
|
1113
1545
|
return {
|
|
@@ -1115,10 +1547,11 @@ async function runValidate(options, global2) {
|
|
|
1115
1547
|
has_warnings: normalizedWarnings.length > 0,
|
|
1116
1548
|
checks,
|
|
1117
1549
|
warnings: normalizedWarnings,
|
|
1550
|
+
...fixes !== void 0 ? { fixes } : {},
|
|
1118
1551
|
generated_at: nowIso()
|
|
1119
1552
|
};
|
|
1120
1553
|
}
|
|
1121
1554
|
export {
|
|
1122
1555
|
runValidate
|
|
1123
1556
|
};
|
|
1124
|
-
//# sourceMappingURL=validate-
|
|
1557
|
+
//# sourceMappingURL=validate-CRFMPTYD.js.map
|