@unbrained/pm-cli 2026.8.9 → 2026.8.10
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/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +40 -0
- package/dist/cli/commander-usage.js +17 -12
- package/dist/cli/help-json-payload.js +51 -16
- package/dist/cli/main.js +7 -6
- package/dist/cli-bundle/bundle-manifest.json +165 -165
- package/dist/cli-bundle/chunks/chunk-2QYH4QMI.js +30 -0
- package/dist/cli-bundle/chunks/{chunk-YC3UF2IO.js → chunk-EBO7OUUE.js} +57 -57
- package/dist/cli-bundle/chunks/{chunk-GMX5YOI3.js → chunk-ETML5C6H.js} +48 -48
- package/dist/cli-bundle/chunks/chunk-JUDU4RO4.js +194 -0
- package/dist/cli-bundle/chunks/{chunk-PYO5GZU6.js → chunk-JZSNADRR.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-EF43KODO.js → chunk-MENWVGJW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-5JO6R4BS.js → chunk-S4EITGLA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-2DTCZXSD.js → chunk-TIGKWVLA.js} +9 -9
- package/dist/cli-bundle/chunks/{chunk-RJC7TPF4.js → chunk-TRWXF476.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TSLDTJLQ.js +2 -0
- package/dist/cli-bundle/chunks/{register-list-query-BUE7PTCU.js → register-list-query-OJ6ZXKV4.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-FC3XLVIK.js → register-mutation-DKI7QC7O.js} +2 -2
- package/dist/cli-bundle/chunks/register-operations-P5OGMT6I.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-UQDTNTLJ.js → register-setup-S3KT2LTH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-6DO4YQWZ.js → chunk-2COZ67XT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-2EXI2DKR.js +4 -0
- package/dist/cli-bundle/focused-chunks/{chunk-KNEHLPBF.js → chunk-34SX654S.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-36FTZ2NT.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-3CQECMKR.js +16 -0
- package/dist/cli-bundle/focused-chunks/chunk-75774JWP.js +6 -0
- package/dist/cli-bundle/focused-chunks/{chunk-MRWVJ3ZG.js → chunk-7UN6BHHO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-VRXJSGIT.js → chunk-CHIBMEZR.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-DZGAHZZV.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-FF4MNAYB.js +153 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZG54B4XG.js → chunk-GHTN2ILR.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-I4YM2I7S.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-IMDTEN7K.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-IW43E4XL.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-3WVHTUAW.js → chunk-JMVA4HKR.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-C3GCHDSQ.js → chunk-KR5RVXLQ.js} +31 -31
- package/dist/cli-bundle/focused-chunks/chunk-KSNJG4KI.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-73FIJONU.js → chunk-M6RPIXKC.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-MXYSIQ56.js +18 -0
- package/dist/cli-bundle/focused-chunks/chunk-RIIN5V4N.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-U46GQJNY.js → chunk-RKWSCYYN.js} +2 -2
- package/dist/cli-bundle/main.js +13 -13
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +38 -38
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +1 -1
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +2 -2
- package/dist/core/diagnostics/remediation.js +9 -9
- package/dist/core/fs/fs-utils.d.ts +10 -0
- package/dist/core/fs/fs-utils.js +16 -4
- package/dist/core/item/item-format.js +3 -32
- package/dist/core/schema/fields-file.d.ts +1 -2
- package/dist/core/schema/fields-file.js +4 -11
- package/dist/core/schema/runtime-schema.js +3 -10
- package/dist/core/schema/status-defs-file.d.ts +1 -2
- package/dist/core/schema/status-defs-file.js +4 -32
- package/dist/core/schema/status-token.d.ts +2 -0
- package/dist/core/schema/status-token.js +32 -0
- package/dist/core/schema/type-workflows.d.ts +1 -2
- package/dist/core/schema/type-workflows.js +4 -11
- package/dist/core/shared/author.d.ts +1 -1
- package/dist/core/shared/author.js +21 -8
- package/dist/core/shared/errors.d.ts +4 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/shared/text-normalization.d.ts +1 -1
- package/dist/core/shared/text-normalization.js +2 -2
- package/dist/sdk/agent/command-recovery.d.ts +4 -0
- package/dist/sdk/agent/command-recovery.js +52 -0
- package/dist/sdk/agent/command-suggestions.d.ts +4 -0
- package/dist/sdk/agent/command-suggestions.js +67 -0
- package/dist/sdk/agent/create-option-policy.d.ts +12 -0
- package/dist/sdk/agent/create-option-policy.js +32 -0
- package/dist/sdk/agent/item-addressing.d.ts +19 -0
- package/dist/sdk/agent/item-addressing.js +208 -0
- package/dist/sdk/cli-bootstrap.d.ts +1 -1
- package/dist/sdk/cli-bootstrap.js +20 -5
- package/dist/sdk/cli-contracts/commander-mutation-options.js +16 -4
- package/dist/sdk/cli-contracts/flag-contracts.js +62 -21
- package/dist/sdk/cli-contracts/registration-helpers.js +10 -2
- package/dist/sdk/cli-contracts/runtime-contracts.js +5 -3
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +6 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +4 -2
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +19 -4
- package/dist/sdk/cli-contracts/tool-schema.js +17 -4
- package/dist/sdk/context-intent-runtime.js +8 -5
- package/dist/sdk/context-signal-store.d.ts +34 -0
- package/dist/sdk/context-signal-store.js +24 -2
- package/dist/sdk/dependency-flag-validation.d.ts +15 -1
- package/dist/sdk/dependency-flag-validation.js +54 -2
- package/dist/sdk/generated-error-code-catalog.js +74 -2
- package/dist/sdk/governance/health.js +14 -7
- package/dist/sdk/governance/provenance-health.d.ts +13 -0
- package/dist/sdk/governance/provenance-health.js +63 -17
- package/dist/sdk/governance/validate-item-reader.d.ts +13 -0
- package/dist/sdk/governance/validate-item-reader.js +18 -0
- package/dist/sdk/governance/validate.d.ts +2 -2
- package/dist/sdk/governance/validate.js +15 -6
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +6 -2
- package/dist/sdk/lifecycle/close.js +17 -14
- package/dist/sdk/lifecycle/create.d.ts +2 -0
- package/dist/sdk/lifecycle/create.js +62 -9
- package/dist/sdk/lifecycle/update-many.js +39 -27
- package/dist/sdk/lifecycle/update.d.ts +6 -1
- package/dist/sdk/lifecycle/update.js +47 -10
- package/dist/sdk/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +3 -3
- package/dist/sdk/merge/install.d.ts +4 -0
- package/dist/sdk/merge/install.js +28 -16
- package/dist/sdk/merge/receipts.d.ts +3 -0
- package/dist/sdk/merge/receipts.js +81 -17
- package/dist/sdk/output-projection.js +24 -4
- package/dist/sdk/query/context.d.ts +2 -0
- package/dist/sdk/query/context.js +7 -4
- package/dist/sdk/query/light-metadata.d.ts +3 -0
- package/dist/sdk/query/light-metadata.js +19 -0
- package/dist/sdk/runtime.d.ts +4 -1
- package/dist/sdk/runtime.js +8 -3
- package/dist/sdk/schema-migration.js +7 -9
- package/dist/sdk/similarity-scoring.d.ts +1 -2
- package/dist/sdk/similarity-scoring.js +4 -16
- package/dist/sdk/workspace-snapshot.d.ts +4 -0
- package/dist/sdk/workspace-snapshot.js +24 -11
- package/docs/AGENT_GUIDE.md +3 -1
- package/docs/COMMANDS.md +8 -5
- package/docs/MERGE_SAFETY.md +7 -5
- package/docs/README.md +2 -5
- package/docs/READ_OUTPUT_CONTRACTS.md +2 -2
- package/docs/SDK.md +33 -8
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +3 -2
- package/docs/SDK_CONTEXT.md +97 -0
- package/docs/SDK_CONTEXT_INTEGRITY.md +18 -3
- package/docs/agent-task-token-baseline.json +2 -2
- package/marketplace.json +2 -2
- package/package.json +5 -4
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +194 -26
- package/dist/cli-bundle/chunks/chunk-5KN4DZYV.js +0 -194
- package/dist/cli-bundle/chunks/chunk-HUV2Z7IS.js +0 -28
- package/dist/cli-bundle/chunks/chunk-MHBVCUF2.js +0 -2
- package/dist/cli-bundle/chunks/register-operations-YH2WAOXU.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2VVP5RAA.js +0 -153
- package/dist/cli-bundle/focused-chunks/chunk-3GSFUDAI.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-4H6MVCK3.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-54TZJ4BM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-5NK5TJ5D.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-JGRSQZJT.js +0 -18
- package/dist/cli-bundle/focused-chunks/chunk-NL57J7BZ.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-P6BBIQRG.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-PZAGVQNN.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-QDAO3XEK.js +0 -14
- package/dist/cli-bundle/focused-chunks/chunk-T4IGQCSY.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-XC2ZW3CJ.js +0 -2
|
@@ -4,10 +4,26 @@
|
|
|
4
4
|
* Reads bounded, privacy-safe provenance resolver outcomes for health checks.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="60154e1b-8348-5b6b-badf-e76bba43bef8")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
const DEFAULT_PROVENANCE_HISTORY_BYTE_LIMIT = 8_388_608;
|
|
11
|
+
const ATTEMPTED_PROVENANCE_OUTCOME_STATUSES = new Set(["resolved", "failed"]);
|
|
12
|
+
const INVALID_PROVENANCE_VALUE_CLASSIFIERS = [
|
|
13
|
+
{
|
|
14
|
+
kind: "boolean",
|
|
15
|
+
matches: (value) => typeof value === "boolean" ||
|
|
16
|
+
(typeof value === "string" && /^(?:true|false)$/iu.test(value.trim())),
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
kind: "single_digit",
|
|
20
|
+
matches: (value) => (typeof value === "number" &&
|
|
21
|
+
Number.isInteger(value) &&
|
|
22
|
+
value >= 0 &&
|
|
23
|
+
value <= 9) ||
|
|
24
|
+
(typeof value === "string" && /^\d$/u.test(value.trim())),
|
|
25
|
+
},
|
|
26
|
+
];
|
|
11
27
|
function isRecord(value) {
|
|
12
28
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13
29
|
}
|
|
@@ -58,22 +74,44 @@ function parseHistoryEntry(line) {
|
|
|
58
74
|
return null;
|
|
59
75
|
}
|
|
60
76
|
}
|
|
61
|
-
function collectResolverOutcomes(entry, aggregates) {
|
|
77
|
+
function collectResolverOutcomes(entry, aggregates, invalidValues) {
|
|
78
|
+
const harness = typeof entry.agent_harness === "string" ? entry.agent_harness : undefined;
|
|
79
|
+
if (harness === undefined)
|
|
80
|
+
return;
|
|
81
|
+
const provenance = isRecord(entry.agent_provenance)
|
|
82
|
+
? entry.agent_provenance
|
|
83
|
+
: {};
|
|
84
|
+
Object.entries(provenance).forEach(([dimension, observation]) => {
|
|
85
|
+
if (!isRecord(observation))
|
|
86
|
+
return;
|
|
87
|
+
const kind = INVALID_PROVENANCE_VALUE_CLASSIFIERS.find((classifier) => classifier.matches(observation.value))?.kind;
|
|
88
|
+
if (!kind)
|
|
89
|
+
return;
|
|
90
|
+
const key = `${harness}\0${dimension}\0${kind}`;
|
|
91
|
+
const aggregate = invalidValues.get(key) ?? {
|
|
92
|
+
harness,
|
|
93
|
+
dimension,
|
|
94
|
+
kind,
|
|
95
|
+
count: 0,
|
|
96
|
+
};
|
|
97
|
+
aggregate.count += 1;
|
|
98
|
+
invalidValues.set(key, aggregate);
|
|
99
|
+
});
|
|
62
100
|
if (!isRecord(entry.context))
|
|
63
101
|
return;
|
|
64
102
|
const outcomes = entry.context.agent_provenance_outcomes;
|
|
65
|
-
if (!isRecord(outcomes)
|
|
103
|
+
if (!isRecord(outcomes))
|
|
66
104
|
return;
|
|
67
|
-
|
|
105
|
+
Object.entries(outcomes).forEach(([dimension, rawOutcome]) => {
|
|
68
106
|
if (!isRecord(rawOutcome) || typeof rawOutcome.resolver !== "string") {
|
|
69
|
-
|
|
107
|
+
return;
|
|
70
108
|
}
|
|
71
|
-
if (
|
|
72
|
-
|
|
109
|
+
if (!ATTEMPTED_PROVENANCE_OUTCOME_STATUSES.has(String(rawOutcome.status))) {
|
|
110
|
+
return;
|
|
73
111
|
}
|
|
74
|
-
const key = `${
|
|
112
|
+
const key = `${harness}\0${dimension}\0${rawOutcome.resolver}`;
|
|
75
113
|
const aggregate = aggregates.get(key) ?? {
|
|
76
|
-
harness
|
|
114
|
+
harness,
|
|
77
115
|
dimension,
|
|
78
116
|
resolver: rawOutcome.resolver,
|
|
79
117
|
attempts: 0,
|
|
@@ -83,9 +121,9 @@ function collectResolverOutcomes(entry, aggregates) {
|
|
|
83
121
|
if (rawOutcome.status === "resolved")
|
|
84
122
|
aggregate.successes += 1;
|
|
85
123
|
aggregates.set(key, aggregate);
|
|
86
|
-
}
|
|
124
|
+
});
|
|
87
125
|
}
|
|
88
|
-
function collectHistoryContent(content, aggregates, eventLimit, initialEventsRead) {
|
|
126
|
+
function collectHistoryContent(content, aggregates, invalidValues, eventLimit, initialEventsRead) {
|
|
89
127
|
let eventsRead = initialEventsRead;
|
|
90
128
|
for (const line of content.split("\n")) {
|
|
91
129
|
if (line.trim().length === 0)
|
|
@@ -95,13 +133,14 @@ function collectHistoryContent(content, aggregates, eventLimit, initialEventsRea
|
|
|
95
133
|
eventsRead += 1;
|
|
96
134
|
const entry = parseHistoryEntry(line);
|
|
97
135
|
if (entry)
|
|
98
|
-
collectResolverOutcomes(entry, aggregates);
|
|
136
|
+
collectResolverOutcomes(entry, aggregates, invalidValues);
|
|
99
137
|
}
|
|
100
138
|
return { eventsRead, truncated: false };
|
|
101
139
|
}
|
|
102
140
|
/** Scan immutable history without failing over malformed streams owned by integrity checks. */
|
|
103
141
|
export async function scanProvenanceResolverHealth(pmRoot, eventLimit = 10_000) {
|
|
104
142
|
const aggregates = new Map();
|
|
143
|
+
const invalidValues = new Map();
|
|
105
144
|
let eventsRead = 0;
|
|
106
145
|
let bytesRead = 0;
|
|
107
146
|
let truncated = false;
|
|
@@ -110,7 +149,7 @@ export async function scanProvenanceResolverHealth(pmRoot, eventLimit = 10_000)
|
|
|
110
149
|
if (history === null)
|
|
111
150
|
continue;
|
|
112
151
|
bytesRead += history.bytesRead;
|
|
113
|
-
const collected = collectHistoryContent(history.content, aggregates, eventLimit, eventsRead);
|
|
152
|
+
const collected = collectHistoryContent(history.content, aggregates, invalidValues, eventLimit, eventsRead);
|
|
114
153
|
eventsRead = collected.eventsRead;
|
|
115
154
|
if (collected.truncated) {
|
|
116
155
|
truncated = true;
|
|
@@ -124,16 +163,23 @@ export async function scanProvenanceResolverHealth(pmRoot, eventLimit = 10_000)
|
|
|
124
163
|
const outcomes = [...aggregates.values()].sort((left, right) => left.harness.localeCompare(right.harness) ||
|
|
125
164
|
left.dimension.localeCompare(right.dimension) ||
|
|
126
165
|
left.resolver.localeCompare(right.resolver));
|
|
166
|
+
const invalidValueFindings = [...invalidValues.values()].sort((left, right) => left.harness.localeCompare(right.harness) ||
|
|
167
|
+
left.dimension.localeCompare(right.dimension) ||
|
|
168
|
+
left.kind.localeCompare(right.kind));
|
|
127
169
|
return {
|
|
128
170
|
outcomes,
|
|
171
|
+
invalid_values: invalidValueFindings,
|
|
129
172
|
warnings: truncated
|
|
130
173
|
? []
|
|
131
|
-
:
|
|
132
|
-
|
|
133
|
-
|
|
174
|
+
: [
|
|
175
|
+
...outcomes
|
|
176
|
+
.filter((outcome) => outcome.attempts > 0 && outcome.successes === 0)
|
|
177
|
+
.map((outcome) => `provenance_resolver_zero_success:${outcome.harness}:${outcome.dimension}:${outcome.resolver}:${String(outcome.attempts)}`),
|
|
178
|
+
...invalidValueFindings.map((finding) => `provenance_value_domain_invalid:${finding.harness}:${finding.dimension}:${finding.kind}:${String(finding.count)}`),
|
|
179
|
+
],
|
|
134
180
|
events_read: eventsRead,
|
|
135
181
|
truncated,
|
|
136
182
|
};
|
|
137
183
|
}
|
|
138
184
|
//# sourceMappingURL=provenance-health.js.map
|
|
139
|
-
//# debugId=
|
|
185
|
+
//# debugId=60154e1b-8348-5b6b-badf-e76bba43bef8
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ItemMetadata, PmSettings } from "../../types/index.js";
|
|
2
|
+
/** Item projection accepted by validate checks; body is read only for strict drift verification. */
|
|
3
|
+
export type ValidateItem = ItemMetadata & {
|
|
4
|
+
body: string;
|
|
5
|
+
};
|
|
6
|
+
/** Load collections for normal checks and add bodies only when history hashes must be verified. */
|
|
7
|
+
export declare function readValidateItems(params: {
|
|
8
|
+
includeBody: boolean;
|
|
9
|
+
pmRoot: string;
|
|
10
|
+
settings: PmSettings;
|
|
11
|
+
typeToFolder: Record<string, string>;
|
|
12
|
+
warnings: string[];
|
|
13
|
+
}): Promise<ValidateItem[]>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/governance/validate-item-reader
|
|
3
|
+
*
|
|
4
|
+
* Selects the least expensive authoritative item projection required by a
|
|
5
|
+
* validation run.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="896ffe11-2cf1-5de0-8d07-5585d4f30c94")}catch(e){}}();
|
|
9
|
+
import { listAllItemMetadata, listAllItemMetadataWithBody, } from "../../core/store/item-store.js";
|
|
10
|
+
/** Load collections for normal checks and add bodies only when history hashes must be verified. */
|
|
11
|
+
export async function readValidateItems(params) {
|
|
12
|
+
if (params.includeBody) {
|
|
13
|
+
return listAllItemMetadataWithBody(params.pmRoot, params.settings.item_format, params.typeToFolder, params.warnings, params.settings.schema);
|
|
14
|
+
}
|
|
15
|
+
return listAllItemMetadata(params.pmRoot, params.settings.item_format, params.typeToFolder, params.warnings, params.settings.schema);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=validate-item-reader.js.map
|
|
18
|
+
//# debugId=896ffe11-2cf1-5de0-8d07-5585d4f30c94
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { type RuntimeStatusRegistry } from "../../core/schema/runtime-schema.js";
|
|
2
2
|
import type { GlobalOptions } from "../../core/shared/command-types.js";
|
|
3
|
-
import { listAllItemMetadataWithBody } from "../../core/store/item-store.js";
|
|
4
3
|
import { type CloseReasonBackfillRow, type EstimateBackfillRow, type StaleLinkPruneRow, type TerminalParentFixRow, type ValidateFixRecord } from "../../core/validate/fix-planning.js";
|
|
5
4
|
import { type DuplicateIssueCode } from "../../core/governance/issue-codes.js";
|
|
6
5
|
import { type MissingFieldOccurrence } from "../../core/validate/missing-by-type.js";
|
|
7
6
|
import type { ValidateMetadataProfile, ValidateMetadataRequiredField } from "../../types/index.js";
|
|
8
7
|
import { type OutputProjectionDeclaration } from "../output-projection.js";
|
|
9
8
|
import { type RelationshipKindRegistry } from "../relationships.js";
|
|
9
|
+
import { type ValidateItem } from "./validate-item-reader.js";
|
|
10
10
|
type ValidateCheckName = "metadata" | "resolution" | "lifecycle" | "dependency_references" | "files" | "command_references" | "history_drift" | "format_version" | "storage_integrity";
|
|
11
11
|
type ValidateStatus = "ok" | "warn" | "error";
|
|
12
12
|
type ValidateDependencyCycleSeverity = "off" | "warn" | "error";
|
|
13
13
|
type ValidateFileScanMode = "default" | "tracked-all" | "tracked-all-strict";
|
|
14
|
-
type ItemWithBody =
|
|
14
|
+
type ItemWithBody = ValidateItem;
|
|
15
15
|
type OrphanedPathClassification = "docs_unowned" | "tests_unowned" | "source_unowned" | "unlinked_existing";
|
|
16
16
|
declare const LIFECYCLE_PATTERN_FIELD_KEYS: readonly ["blocked_reason", "resolution", "actual_result"];
|
|
17
17
|
type LifecyclePatternFieldKey = (typeof LIFECYCLE_PATTERN_FIELD_KEYS)[number];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm validate command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b5b7e497-f067-5504-9ffa-fd177997c518")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import { realpathSync } from "node:fs";
|
|
10
10
|
import { execFile } from "node:child_process";
|
|
@@ -23,7 +23,6 @@ import { PmCliError } from "../../core/shared/errors.js";
|
|
|
23
23
|
import { toNonEmptyStringOrUndefined } from "../../core/shared/primitives.js";
|
|
24
24
|
import { nowIso } from "../../core/shared/time.js";
|
|
25
25
|
import { CURRENT_ITEM_FORMAT_VERSION, effectiveItemFormatVersion, scanItemFormatVersions, } from "../../core/item/item-format-version.js";
|
|
26
|
-
import { listAllItemMetadataWithBody } from "../../core/store/item-store.js";
|
|
27
26
|
import { getSettingsPath, resolvePmRoot } from "../../core/store/paths.js";
|
|
28
27
|
import { readSettings } from "../../core/store/settings.js";
|
|
29
28
|
import { partitionFixesByGrant, planCloseReasonBackfillFixes, planEstimateBackfillFixes, planResolutionBackfillFixes, planStaleLinkPruneFixes, planTerminalParentFixes, resolveGrantedFixScopes, toFixOutputRow, } from "../../core/validate/fix-planning.js";
|
|
@@ -43,6 +42,7 @@ import { createRelationshipKindRegistry, } from "../relationships.js";
|
|
|
43
42
|
import { runDocs } from "../docs.js";
|
|
44
43
|
import { runFiles } from "../files.js";
|
|
45
44
|
import { extractReferencedPmItemIdsFromCommand } from "../test/linked-command-detection.js";
|
|
45
|
+
import { readValidateItems, } from "./validate-item-reader.js";
|
|
46
46
|
const FILE_SCAN_DIRECTORIES = ["src", "tests", "docs"];
|
|
47
47
|
const FILE_SCAN_ROOT_FILES = [
|
|
48
48
|
"README.md",
|
|
@@ -2100,7 +2100,10 @@ async function buildStorageIntegrityCheck(pmRoot, items, typeToFolder, settings)
|
|
|
2100
2100
|
}
|
|
2101
2101
|
const pendingMergeReceipts = gitWorkspaceRoot === null
|
|
2102
2102
|
? []
|
|
2103
|
-
: await listMergeReceipts(gitWorkspaceRoot, {
|
|
2103
|
+
: await listMergeReceipts(gitWorkspaceRoot, {
|
|
2104
|
+
includeLossless: true,
|
|
2105
|
+
pmRoot,
|
|
2106
|
+
});
|
|
2104
2107
|
const { pendingDecisions: pendingMergeDecisions, lossless: losslessMergeReceipts, } = partitionMergeReceipts(pendingMergeReceipts);
|
|
2105
2108
|
if (pendingMergeDecisions.length > 0) {
|
|
2106
2109
|
warnings.push(`validate_merge_decisions_unreviewed:${pendingMergeDecisions.length}`);
|
|
@@ -2262,9 +2265,15 @@ export async function runValidate(options, global, services = {}) {
|
|
|
2262
2265
|
const settings = await readSettings(pmRoot);
|
|
2263
2266
|
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
2264
2267
|
const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
|
|
2265
|
-
const itemReadWarnings = [];
|
|
2266
|
-
const items = await listAllItemMetadataWithBody(pmRoot, settings.item_format, typeRegistry.type_to_folder, itemReadWarnings, settings.schema);
|
|
2267
2268
|
const requestedChecks = resolveRequestedChecks(options);
|
|
2269
|
+
const itemReadWarnings = [];
|
|
2270
|
+
const items = await readValidateItems({
|
|
2271
|
+
includeBody: requestedChecks.has("history_drift"),
|
|
2272
|
+
pmRoot,
|
|
2273
|
+
settings,
|
|
2274
|
+
typeToFolder: typeRegistry.type_to_folder,
|
|
2275
|
+
warnings: itemReadWarnings,
|
|
2276
|
+
});
|
|
2268
2277
|
if (requestedChecks.has("history_drift")) {
|
|
2269
2278
|
const authorAttribution = await scanHistoryAuthorAttribution(pmRoot);
|
|
2270
2279
|
if (authorAttribution.actionable_unknown_event_count > 0) {
|
|
@@ -2337,4 +2346,4 @@ export async function runValidate(options, global, services = {}) {
|
|
|
2337
2346
|
}
|
|
2338
2347
|
/* c8 ignore stop */
|
|
2339
2348
|
//# sourceMappingURL=validate.js.map
|
|
2340
|
-
//# debugId=
|
|
2349
|
+
//# debugId=b5b7e497-f067-5504-9ffa-fd177997c518
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -17,6 +17,10 @@ export { SNAPSHOT_SCHEMA, createWorkspaceSnapshot, deleteWorkspaceSnapshot, insp
|
|
|
17
17
|
export { flushTelemetryQueue } from "./telemetry-flush.js";
|
|
18
18
|
export { EXECUTABLE_COMMAND_ALIASES, applyBootstrapPagerPolicy, coalesceRepeatedListFlags, listAliasPluralKeys, mergeLinkedTestTwoTokenEntries, normalizeBootstrapInvocation, normalizeLegacyExtensionActionSyntax, parseBootstrapCommandName, parseBootstrapGlobalOptions, parseBootstrapHelpRequest, parseBootstrapTypeValue, stripGlobalBootstrapTokens, type BootstrapGlobalOptions, type BootstrapHelpRequest, type BootstrapInvocationNormalizationResult, type BootstrapNormalizationEvent, } from "./cli-bootstrap.js";
|
|
19
19
|
export { quoteCommandArg, quoteWindowsCommandArg, renderPmCommand, } from "./command-line.js";
|
|
20
|
+
export * from "./agent/command-recovery.js";
|
|
21
|
+
export * from "./agent/command-suggestions.js";
|
|
22
|
+
export * from "./agent/item-addressing.js";
|
|
23
|
+
export * from "./agent/create-option-policy.js";
|
|
20
24
|
export { runGc, type GcCheckpointsSummary, type GcLocksSummary, } from "./governance/gc.js";
|
|
21
25
|
export { _testOnlyHealthCommand, runHealth, type HealthCheck, } from "./governance/health.js";
|
|
22
26
|
export { _testOnlyValidateCommand, projectValidateCounts, runValidate, type ValidateCheck, type ValidateCountsFixesSummary, type ValidateCountsResult, type ValidateFixesSummary, type ValidateMutationServices, } from "./governance/validate.js";
|
package/dist/sdk/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Defines public SDK APIs and package-author helpers for Index.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="99d427a5-1f09-5ca4-8c1f-8b9d54bfd2f2")}catch(e){}}();
|
|
8
8
|
export { PM_COMMAND_VISIBILITY_CONTRACTS, PM_MCP_PROMPT_CONTRACTS, PM_MCP_RESOURCE_CONTRACTS, PM_MCP_TOOL_COMMAND_CONTRACTS, listPmCommandsForTier, listPmMcpToolsForProfile, renderPmCommandVisibilityMarkdown, resolvePmCommandVisibilityTier, } from "./agent-capability-contracts.js";
|
|
9
9
|
export * from "./agent-session-context.js";
|
|
10
10
|
export { isErrnoError, limitAnnotationEntries, parseAnnotationTextInput, readAnnotationEntries, normalizeAnnotationTransportOptions, resolveAnnotationInput, resolveAnnotationIndex, runAnnotationCommand, wrapOwnershipConflict, } from "./annotations.js";
|
|
@@ -18,6 +18,10 @@ export { SNAPSHOT_SCHEMA, createWorkspaceSnapshot, deleteWorkspaceSnapshot, insp
|
|
|
18
18
|
export { flushTelemetryQueue } from "./telemetry-flush.js";
|
|
19
19
|
export { EXECUTABLE_COMMAND_ALIASES, applyBootstrapPagerPolicy, coalesceRepeatedListFlags, listAliasPluralKeys, mergeLinkedTestTwoTokenEntries, normalizeBootstrapInvocation, normalizeLegacyExtensionActionSyntax, parseBootstrapCommandName, parseBootstrapGlobalOptions, parseBootstrapHelpRequest, parseBootstrapTypeValue, stripGlobalBootstrapTokens, } from "./cli-bootstrap.js";
|
|
20
20
|
export { quoteCommandArg, quoteWindowsCommandArg, renderPmCommand, } from "./command-line.js";
|
|
21
|
+
export * from "./agent/command-recovery.js";
|
|
22
|
+
export * from "./agent/command-suggestions.js";
|
|
23
|
+
export * from "./agent/item-addressing.js";
|
|
24
|
+
export * from "./agent/create-option-policy.js";
|
|
21
25
|
export { runGc, } from "./governance/gc.js";
|
|
22
26
|
export { _testOnlyHealthCommand, runHealth, } from "./governance/health.js";
|
|
23
27
|
export { _testOnlyValidateCommand, projectValidateCounts, runValidate, } from "./governance/validate.js";
|
|
@@ -141,4 +145,4 @@ export * from "./governance.js";
|
|
|
141
145
|
export * from "./query.js";
|
|
142
146
|
export * from "./testing.js";
|
|
143
147
|
//# sourceMappingURL=index.js.map
|
|
144
|
-
//# debugId=
|
|
148
|
+
//# debugId=99d427a5-1f09-5ca4-8c1f-8b9d54bfd2f2
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Implements the pm close command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="83affe54-a56c-5d84-b6b0-9634d4238ff5")}catch(e){}}();
|
|
8
8
|
import { pathExists, toItemRecord, isTerminalStatus, resolveItemTypeRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, PmCliError, buildItemNotFoundError, listAllItemMetadataLight, locateItem, mutateItem, readLocatedItem, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, resolveIsoOrRelative, shouldCompletePlanOnClose, getActiveExtensionRegistrations, } from "../runtime-primitives.js";
|
|
9
|
-
import { collectBlockedByIds, indexBlockedByIds
|
|
9
|
+
import { collectBlockedByIds, indexBlockedByIds } from "../actionability.js";
|
|
10
10
|
import { applyTerminalOrderingPolicy, requireTerminalReason, } from "../lifecycle-policy.js";
|
|
11
11
|
import { renderPmCommand } from "../command-line.js";
|
|
12
12
|
const CLOSE_VALIDATION_FIELDS = [
|
|
@@ -40,7 +40,7 @@ function findMissingCloseValidationFields(itemMetadata) {
|
|
|
40
40
|
for (const field of CLOSE_VALIDATION_FIELDS) {
|
|
41
41
|
const rawValue = itemMetadata[field.key];
|
|
42
42
|
if (typeof rawValue !== "string" || rawValue.trim().length === 0) {
|
|
43
|
-
missing.push(field
|
|
43
|
+
missing.push(field);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
return missing;
|
|
@@ -259,32 +259,34 @@ function applyDuplicateCloseMetadata(metadata, duplicateOf) {
|
|
|
259
259
|
}
|
|
260
260
|
return duplicateFallbackFields;
|
|
261
261
|
}
|
|
262
|
-
function collectCloseValidationWarnings(metadata, validateCloseMode, activeChildIds,
|
|
262
|
+
function collectCloseValidationWarnings(metadata, validateCloseMode, activeChildIds, pmRoot) {
|
|
263
263
|
const warnings = [];
|
|
264
264
|
if (validateCloseMode !== "off") {
|
|
265
265
|
const missingFields = findMissingCloseValidationFields(metadata);
|
|
266
266
|
if (missingFields.length > 0) {
|
|
267
|
+
const missingLabels = missingFields.map((field) => field.label);
|
|
267
268
|
if (validateCloseMode === "strict") {
|
|
268
|
-
const missingFlags = missingFields.map((field) => `--${field.replaceAll("_", "-")}`);
|
|
269
|
-
const
|
|
270
|
-
"
|
|
269
|
+
const missingFlags = missingFields.map((field) => `--${field.key.replaceAll("_", "-")}`);
|
|
270
|
+
const updateTokens = [
|
|
271
|
+
"--pm-path",
|
|
272
|
+
pmRoot,
|
|
273
|
+
"update",
|
|
271
274
|
metadata.id,
|
|
272
|
-
closeReason ?? "<reason>",
|
|
273
275
|
...missingFlags.flatMap((flag) => [flag, "<value>"]),
|
|
274
276
|
];
|
|
275
|
-
throw new PmCliError(`Cannot close item ${metadata.id}: missing ${
|
|
277
|
+
throw new PmCliError(`Cannot close item ${metadata.id}: missing ${missingLabels.join(", ")}. Populate fields or use --validate-close warn.`, EXIT_CODE.USAGE, {
|
|
276
278
|
code: "close_validation_missing_fields",
|
|
277
279
|
recovery: {
|
|
278
280
|
missing: missingFlags,
|
|
279
|
-
suggested_retry: renderPmCommand(
|
|
281
|
+
suggested_retry: renderPmCommand(updateTokens),
|
|
280
282
|
},
|
|
281
283
|
nextSteps: [
|
|
282
|
-
"
|
|
284
|
+
"Run the suggested pm update, then retry the original pm close invocation.",
|
|
283
285
|
"Use --validate-close warn only when governance permits an evidenced exception.",
|
|
284
286
|
],
|
|
285
287
|
});
|
|
286
288
|
}
|
|
287
|
-
warnings.push(`close_validation_missing_fields:${metadata.id}:${
|
|
289
|
+
warnings.push(`close_validation_missing_fields:${metadata.id}:${missingLabels.join(",")}`);
|
|
288
290
|
}
|
|
289
291
|
if (activeChildIds.length > 0) {
|
|
290
292
|
if (validateCloseMode === "strict") {
|
|
@@ -320,7 +322,7 @@ function mutateCloseMetadata(metadata, context) {
|
|
|
320
322
|
}
|
|
321
323
|
const inlineChangedFields = applyInlineCloseFields(metadata, context.options);
|
|
322
324
|
const duplicateFallbackFields = applyDuplicateCloseMetadata(metadata, context.duplicateOf);
|
|
323
|
-
const mutationWarnings = collectCloseValidationWarnings(metadata, context.validateCloseMode, context.activeChildIds, context.
|
|
325
|
+
const mutationWarnings = collectCloseValidationWarnings(metadata, context.validateCloseMode, context.activeChildIds, context.pmRoot);
|
|
324
326
|
metadata.status = context.statusRegistry.close_status;
|
|
325
327
|
metadata.closed_at = context.closedAt;
|
|
326
328
|
const shouldWriteCompletedAt = context.options.completedAt !== undefined ||
|
|
@@ -428,6 +430,7 @@ export async function closeItem(id, closeReasonText, options, global) {
|
|
|
428
430
|
force: options.force,
|
|
429
431
|
mutate(document) {
|
|
430
432
|
return mutateCloseMetadata(document.metadata, {
|
|
433
|
+
pmRoot,
|
|
431
434
|
statusRegistry,
|
|
432
435
|
force: options.force,
|
|
433
436
|
options,
|
|
@@ -455,4 +458,4 @@ export function runClose(id, closeReasonText, options, global) {
|
|
|
455
458
|
return closeItem(id, closeReasonText, options, global);
|
|
456
459
|
}
|
|
457
460
|
//# sourceMappingURL=close.js.map
|
|
458
|
-
//# debugId=
|
|
461
|
+
//# debugId=83affe54-a56c-5d84-b6b0-9634d4238ff5
|
|
@@ -34,6 +34,8 @@ export interface CreateCommandOptions extends MutationMetadataCommandOptions, Sh
|
|
|
34
34
|
body?: string;
|
|
35
35
|
/** Value that configures or reports allow missing parent for this contract. */
|
|
36
36
|
allowMissingParent?: boolean;
|
|
37
|
+
/** Explicitly permit unresolved local dependency targets with warning receipts. */
|
|
38
|
+
allowUnresolvedDeps?: boolean;
|
|
37
39
|
/** Value that configures or reports template for this contract. */
|
|
38
40
|
template?: string;
|
|
39
41
|
/** Creates mode using the validated operation inputs. */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm create command surface and its agent-facing runtime behavior.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
7
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ffa56c1a-d98c-566a-81c5-4ad5608aa26c")}catch(e){}}();
|
|
8
8
|
import { pathExists, removeFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, generateItemId, normalizeItemId, canonicalDocument, normalizeItemMetadata, serializeItemDocument, assertParentReferenceIsNotSelf, isPlaceholderReferenceToken, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, resolvePriority, getFocusedItem, normalizeStatusInput, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, acquireLock, printError, buildInvalidTypeError, resolveTypeSynonym, collectRuntimeCreateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, ITEM_METADATA_KEY_ORDER, PmCliError, nowIso, resolveIsoOrRelative, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveCommandHandler, runActiveBeforeMutationHooks, runActiveOnWriteHooks, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, listAllItemMetadataLight, locateItem, createMutationGuardSdk, getHistoryPath, getItemPath, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
|
|
9
9
|
import { requireTerminalReasonWithRecovery } from "../lifecycle-policy.js";
|
|
10
10
|
import { evaluateSimilarityGovernance, similarityAdvisoryWarnings, } from "../similarity.js";
|
|
@@ -17,9 +17,10 @@ import { parseLinkedTestAssertionEqualsMap, parseLinkedTestAssertionGteMap, pars
|
|
|
17
17
|
import { looksLikeStructuredLinkedTestEntry, normalizeStructuredLinkedTestEntry, } from "../test/entry.js";
|
|
18
18
|
import { COMMON_UNSET_FIELD_DEFINITIONS_AFTER_AUTHOR, COMMON_UNSET_FIELD_DEFINITIONS_BEFORE_AUTHOR, parseCommandUnsetTargets, resolveRuntimeUnsetFieldDefinition, } from "./shared-unset-fields.js";
|
|
19
19
|
import { ensureEnumValue } from "./recurrence-parsers.js";
|
|
20
|
-
import { assertDependencyEdgesAllowed, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
|
|
20
|
+
import { assertDependencyEdgesAllowed, assertDependencyTargetsResolvable, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
|
|
21
21
|
import { normalizeDependencySeedId, normalizeDependencySourceKind, } from "../dependency-provenance.js";
|
|
22
22
|
import { resolveCanonicalRelationshipKind } from "../relationships.js";
|
|
23
|
+
import { supportsCreateExplicitEmpty } from "../agent/create-option-policy.js";
|
|
23
24
|
import { parseEventEntries, parseReminderEntries, parseTypeOptionEntries, } from "./repeatable-metadata-parsers.js";
|
|
24
25
|
import { DEPENDENCY_KIND_VALUES, ISSUE_SEVERITY_VALUES, RISK_VALUES, SCOPE_VALUES, } from "../../types/index.js";
|
|
25
26
|
const CREATE_MODE_VALUES = ["strict", "progressive"];
|
|
@@ -515,7 +516,7 @@ function assertNoStrictRequiredOptionClears(requiredOptions, createMode, clearOp
|
|
|
515
516
|
if (createMode !== "strict") {
|
|
516
517
|
return;
|
|
517
518
|
}
|
|
518
|
-
const strictRequiredClears = requiredOptions.filter((required) => clearOptionKeys.has(required));
|
|
519
|
+
const strictRequiredClears = requiredOptions.filter((required) => clearOptionKeys.has(required) && !supportsCreateExplicitEmpty(required));
|
|
519
520
|
if (strictRequiredClears.length === 0) {
|
|
520
521
|
return;
|
|
521
522
|
}
|
|
@@ -613,6 +614,10 @@ function requireCreateOptionByType(typeDefinition, options, createMode, clearOpt
|
|
|
613
614
|
if (optionKey === "status" && typeDefinition.default_status !== undefined) {
|
|
614
615
|
return true;
|
|
615
616
|
}
|
|
617
|
+
if (clearOptionKeys.has(optionKey) &&
|
|
618
|
+
supportsCreateExplicitEmpty(optionKey)) {
|
|
619
|
+
return true;
|
|
620
|
+
}
|
|
616
621
|
return hasCreateOptionValue(optionLookup, optionKey);
|
|
617
622
|
};
|
|
618
623
|
const missingRequiredOptions = policyState.required.filter((required) => !satisfiesRequiredOption(required));
|
|
@@ -1030,6 +1035,7 @@ function collectTemplateCustomTypeOptions(typeDefinition, resolvedOptions) {
|
|
|
1030
1035
|
/** Resolve the target item type and creation mode for `pm create`: merge any `--template` options, apply the governance default-type fallback, map a near-miss `--type` to its canonical synonym (never blocking), and derive the schedule preset and effective create mode. Returns the (possibly template-merged) options alongside the resolved type definition, canonical type name, schedule preset, and create mode. */
|
|
1031
1036
|
async function resolveCreateTypeSelection(options, global, pmRoot, settings, typeRegistry) {
|
|
1032
1037
|
let resolvedOptions = options;
|
|
1038
|
+
const warnings = [];
|
|
1033
1039
|
if (resolvedOptions.template !== undefined) {
|
|
1034
1040
|
const templateName = resolvedOptions.template.trim();
|
|
1035
1041
|
if (templateName.length === 0) {
|
|
@@ -1056,7 +1062,7 @@ async function resolveCreateTypeSelection(options, global, pmRoot, settings, typ
|
|
|
1056
1062
|
? resolveTypeName(synonymCanonical, typeRegistry)
|
|
1057
1063
|
: undefined;
|
|
1058
1064
|
if (synonymResolved) {
|
|
1059
|
-
|
|
1065
|
+
warnings.push(`type_coercion:${resolvedOptions.type.trim()}:${synonymResolved}`);
|
|
1060
1066
|
resolvedOptions.type = synonymResolved;
|
|
1061
1067
|
resolvedTypeName = synonymResolved;
|
|
1062
1068
|
}
|
|
@@ -1089,7 +1095,14 @@ async function resolveCreateTypeSelection(options, global, pmRoot, settings, typ
|
|
|
1089
1095
|
throw new PmCliError(`--schedule-preset ${schedulePreset} is only supported for Reminder, Meeting, or Event types`, EXIT_CODE.USAGE);
|
|
1090
1096
|
}
|
|
1091
1097
|
const createMode = resolveEffectiveCreateMode(resolvedOptions.createMode, schedulePreset, settings.governance.create_mode_default);
|
|
1092
|
-
return {
|
|
1098
|
+
return {
|
|
1099
|
+
resolvedOptions,
|
|
1100
|
+
typeDefinition,
|
|
1101
|
+
type,
|
|
1102
|
+
schedulePreset,
|
|
1103
|
+
createMode,
|
|
1104
|
+
warnings,
|
|
1105
|
+
};
|
|
1093
1106
|
}
|
|
1094
1107
|
/** Seed the explicit-unset and clear-option key sets from the parsed `--unset` targets, then fold in each enabled `--clear-<collection>` flag: it marks the collection's item-metadata key as explicitly unset and its option key as cleared, and rejects combining a clear flag with its own value flag. Returns the augmented sets used downstream for required-flag relaxation and history messaging. */
|
|
1095
1108
|
function collectCreateClearTargets(resolvedOptions, unsetTargets) {
|
|
@@ -1310,11 +1323,31 @@ function assertNoCreateFieldUnsetConflicts(registeredItemFieldValues, runtimeCre
|
|
|
1310
1323
|
}
|
|
1311
1324
|
/** Throw the aggregated `missing_required_option` error when a type's required create options and/or required type-option keys were not all supplied in one invocation. Builds a type-aware valid example and staged-onboarding next steps (a strict-mode invocation also carries a compact recovery envelope). A no-op when nothing is missing. */
|
|
1312
1325
|
function assertNoMissingRequiredCreateOptions(params) {
|
|
1313
|
-
const { combinedMissingFlags, typeDefinition, missingRequiredCreateFlags, missingRequiredTypeOptionKeys, openStatus, type, createMode, } = params;
|
|
1326
|
+
const { combinedMissingFlags, typeDefinition, missingRequiredCreateFlags, missingRequiredTypeOptionKeys, openStatus, type, createMode, missingRequiredRuntimeFields, } = params;
|
|
1314
1327
|
if (combinedMissingFlags.length === 0) {
|
|
1315
1328
|
return;
|
|
1316
1329
|
}
|
|
1317
|
-
const
|
|
1330
|
+
const runtimeFieldSyntax = missingRequiredRuntimeFields.map((field) => {
|
|
1331
|
+
const placeholder = field.type === "boolean"
|
|
1332
|
+
? "<true|false>"
|
|
1333
|
+
: field.type === "array"
|
|
1334
|
+
? "<json-array>"
|
|
1335
|
+
: field.type === "object"
|
|
1336
|
+
? "<json-object>"
|
|
1337
|
+
: field.type === "number"
|
|
1338
|
+
? "<number>"
|
|
1339
|
+
: field.type === "string_array" || field.repeatable
|
|
1340
|
+
? "<value>"
|
|
1341
|
+
: "<string>";
|
|
1342
|
+
return {
|
|
1343
|
+
example: `--${field.cli_flag} ${placeholder}`,
|
|
1344
|
+
description: `--${field.cli_flag} maps to ${field.metadata_key} (${field.type}${field.repeatable ? ", repeatable" : ""})`,
|
|
1345
|
+
};
|
|
1346
|
+
});
|
|
1347
|
+
const nextValidExample = [
|
|
1348
|
+
buildTypeSpecificCreateExample(typeDefinition, missingRequiredCreateFlags, missingRequiredTypeOptionKeys, openStatus),
|
|
1349
|
+
...runtimeFieldSyntax.map((field) => field.example),
|
|
1350
|
+
].join(" ");
|
|
1318
1351
|
const nextSteps = [
|
|
1319
1352
|
`Run "pm create --help --type ${type}" for type-aware required option guidance.`,
|
|
1320
1353
|
];
|
|
@@ -1329,6 +1362,9 @@ function assertNoMissingRequiredCreateOptions(params) {
|
|
|
1329
1362
|
nextSteps.push('For minimal scheduling inputs, try "--schedule-preset lightweight".');
|
|
1330
1363
|
}
|
|
1331
1364
|
}
|
|
1365
|
+
if (runtimeFieldSyntax.length > 0) {
|
|
1366
|
+
nextSteps.push(`Required custom field formats: ${runtimeFieldSyntax.map((field) => field.description).join("; ")}.`);
|
|
1367
|
+
}
|
|
1332
1368
|
const errorMessage = combinedMissingFlags.length === 1
|
|
1333
1369
|
? `Missing required option ${combinedMissingFlags[0]} for type "${type}"`
|
|
1334
1370
|
: `Missing required options ${combinedMissingFlags.join(", ")} for type "${type}"`;
|
|
@@ -1553,6 +1589,8 @@ export async function runCreate(options, global) {
|
|
|
1553
1589
|
const extensionFieldNames = collectRegisteredItemFieldNames(extensionRegistrations);
|
|
1554
1590
|
const registeredItemFieldValues = parseRegisteredItemFieldAssignments(resolvedOptions.field, extensionRegistrations);
|
|
1555
1591
|
const runtimeCreateFieldValues = collectRuntimeCreateFieldValues(resolvedOptions, runtimeFieldRegistry, type);
|
|
1592
|
+
const missingRequiredRuntimeFlagSet = new Set(runtimeCreateFieldValues.missing_required_flags);
|
|
1593
|
+
const missingRequiredRuntimeFields = runtimeFieldRegistry.definitions.filter((field) => missingRequiredRuntimeFlagSet.has(`--${field.cli_flag}`));
|
|
1556
1594
|
assertNoCreateFieldUnsetConflicts(registeredItemFieldValues, runtimeCreateFieldValues, unsetTargets);
|
|
1557
1595
|
const missingRequiredTypeOptionKeys = collectMissingRequiredTypeOptionKeys(validatedTypeOptions.errors, type);
|
|
1558
1596
|
const missingRequiredTypeOptionFlags = missingRequiredTypeOptionKeys.map((key) => `--type-option ${key}=<value>`);
|
|
@@ -1572,6 +1610,7 @@ export async function runCreate(options, global) {
|
|
|
1572
1610
|
openStatus: statusRegistry.open_status,
|
|
1573
1611
|
type,
|
|
1574
1612
|
createMode,
|
|
1613
|
+
missingRequiredRuntimeFields,
|
|
1575
1614
|
});
|
|
1576
1615
|
assertNoInvalidTypeOptions(validatedTypeOptions.errors, type, typeDefinition, statusRegistry);
|
|
1577
1616
|
const id = await resolveCreateItemId({
|
|
@@ -1619,7 +1658,10 @@ export async function runCreate(options, global) {
|
|
|
1619
1658
|
? "warn"
|
|
1620
1659
|
: settings.validation.parent_reference;
|
|
1621
1660
|
const sprintReleasePolicy = settings.validation.sprint_release_format;
|
|
1622
|
-
const validationWarnings =
|
|
1661
|
+
const validationWarnings = [
|
|
1662
|
+
...typeSelection.warnings,
|
|
1663
|
+
...collectCreateScheduleWarnings(type, id, deadline, reminders.values, events.values),
|
|
1664
|
+
];
|
|
1623
1665
|
const parentValidation = await resolveCreateParentWithWarnings({
|
|
1624
1666
|
itemId: id,
|
|
1625
1667
|
parent,
|
|
@@ -1651,6 +1693,14 @@ export async function runCreate(options, global) {
|
|
|
1651
1693
|
});
|
|
1652
1694
|
const dependencyValues = blockedByResolution.dependencyValues;
|
|
1653
1695
|
assertDependencyEdgesAllowed(id, dependencyValues);
|
|
1696
|
+
validationWarnings.push(...(await assertDependencyTargetsResolvable({
|
|
1697
|
+
pmRoot,
|
|
1698
|
+
dependencies: dependencyValues,
|
|
1699
|
+
idPrefix: settings.id_prefix,
|
|
1700
|
+
itemFormat: settings.item_format,
|
|
1701
|
+
typeToFolder: typeRegistry.type_to_folder,
|
|
1702
|
+
allowUnresolved: resolvedOptions.allowUnresolvedDeps,
|
|
1703
|
+
})));
|
|
1654
1704
|
status = blockedByResolution.status;
|
|
1655
1705
|
const blockedReason = resolveUnsettableOptionalString(unsetKeys, "blocked_reason", resolvedOptions.blockedReason);
|
|
1656
1706
|
const unblockNote = resolveUnsettableOptionalString(unsetKeys, "unblock_note", resolvedOptions.unblockNote);
|
|
@@ -1788,6 +1838,9 @@ export async function runCreate(options, global) {
|
|
|
1788
1838
|
allowDuplicate: resolvedOptions.allowDuplicate,
|
|
1789
1839
|
});
|
|
1790
1840
|
const outputItem = structuredClone(itemMetadata);
|
|
1841
|
+
if (createMode === "strict" && explicitUnsets.has("dependencies")) {
|
|
1842
|
+
outputItem.dependencies = [];
|
|
1843
|
+
}
|
|
1791
1844
|
// GH-216: nudge agents toward the underutilized in_progress state instead of
|
|
1792
1845
|
// jumping open -> closed. Only surfaces for workable types created in the open
|
|
1793
1846
|
// status when the workflow defines a distinct in_progress status to move to.
|
|
@@ -1835,4 +1888,4 @@ export const _testOnlyCreateCommand = {
|
|
|
1835
1888
|
typeOptionExampleValue,
|
|
1836
1889
|
};
|
|
1837
1890
|
//# sourceMappingURL=create.js.map
|
|
1838
|
-
//# debugId=
|
|
1891
|
+
//# debugId=ffa56c1a-d98c-566a-81c5-4ad5608aa26c
|