@unbrained/pm-cli 2026.8.27 → 2026.8.29
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 +49 -1
- package/dist/cli/error-guidance.js +61 -7
- package/dist/cli/register-annotations.js +58 -41
- package/dist/cli-bundle/bundle-manifest.json +142 -142
- package/dist/cli-bundle/chunks/{chunk-TNX6HC54.js → chunk-2MKLQL2E.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SKXLJIEK.js → chunk-2UETTHY6.js} +49 -49
- package/dist/cli-bundle/chunks/{chunk-SHMDY36D.js → chunk-3TEF3HM5.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SH6P7FXI.js → chunk-7SKMLSMX.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-7X6OZEIV.js +34 -0
- package/dist/cli-bundle/chunks/{chunk-CVBBGWW5.js → chunk-CMIEDWAY.js} +54 -50
- package/dist/cli-bundle/chunks/{chunk-3OO3W6FW.js → chunk-GNWPTEBW.js} +64 -61
- package/dist/cli-bundle/chunks/chunk-MTTKAUBX.js +2 -0
- package/dist/cli-bundle/chunks/chunk-N6OR6FAR.js +13 -0
- package/dist/cli-bundle/chunks/{chunk-R4ETAOJC.js → chunk-TGNAA66W.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-52EKTW6V.js → chunk-WS2GJQVG.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-EUWM6VII.js → register-list-query-OMKJ5ONN.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-FD4HSAVU.js → register-mutation-QBSNCOY3.js} +4 -4
- package/dist/cli-bundle/chunks/{register-operations-HRMNFEC3.js → register-operations-UC77FQZC.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-33GNICLX.js → register-setup-GLQ5SYV3.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-HC7ODMH3.js → chunk-3AVAWVZA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3UMBF26I.js +158 -0
- package/dist/cli-bundle/focused-chunks/{chunk-YVVZ3LQ6.js → chunk-73EDXGYE.js} +16 -15
- package/dist/cli-bundle/focused-chunks/{chunk-4BR5UU52.js → chunk-AXZ5AJAF.js} +45 -45
- package/dist/cli-bundle/focused-chunks/{chunk-MXTYGECH.js → chunk-G6PATS5E.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-SUBSWYW3.js → chunk-JZYPPMXF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-LLNTHF5X.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-LYFWQMVC.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-RKOKG43G.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-TDK3OCX3.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-EKX37ZHA.js → chunk-THEPQMLX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FC2AXLB5.js → chunk-XXOWRJZ5.js} +2 -2
- package/dist/cli-bundle/main.js +14 -14
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +31 -32
- 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 +34 -32
- 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 +10 -10
- package/dist/core/diagnostics/remediation.js +16 -6
- package/dist/core/history/drift-scan.d.ts +2 -0
- package/dist/core/history/drift-scan.js +72 -36
- package/dist/core/history/history.d.ts +3 -3
- package/dist/core/history/history.js +5 -5
- package/dist/core/history/replay.d.ts +1 -1
- package/dist/core/history/replay.js +50 -19
- package/dist/core/item/actionability.d.ts +7 -1
- package/dist/core/item/actionability.js +44 -11
- package/dist/core/item/dependency-reference.d.ts +10 -0
- package/dist/core/item/dependency-reference.js +21 -0
- package/dist/core/item/parse.d.ts +4 -0
- package/dist/core/item/parse.js +38 -16
- package/dist/core/shared/author.js +69 -17
- package/dist/mcp/tool-definitions.js +5 -5
- package/dist/sdk/agent/command-recovery.js +3 -3
- package/dist/sdk/agent/task-transcript-contracts.d.ts +52 -0
- package/dist/sdk/agent/task-transcript-contracts.js +198 -0
- package/dist/sdk/annotations.d.ts +5 -2
- package/dist/sdk/annotations.js +66 -36
- package/dist/sdk/cli-bootstrap.d.ts +2 -8
- package/dist/sdk/cli-bootstrap.js +7 -67
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.d.ts +23 -0
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +80 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +5 -2
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +5 -5
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +15 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +16 -3
- package/dist/sdk/comments.d.ts +4 -0
- package/dist/sdk/comments.js +2 -2
- package/dist/sdk/completion.js +9 -5
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +3 -2
- package/dist/sdk/dependency-provenance.d.ts +51 -2
- package/dist/sdk/dependency-provenance.js +91 -7
- package/dist/sdk/extension/install-sources.d.ts +8 -1
- package/dist/sdk/extension/install-sources.js +132 -39
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +74 -14
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +86 -38
- package/dist/sdk/governance/health.js +86 -22
- package/dist/sdk/governance/validate-history-drift.js +5 -2
- package/dist/sdk/graph/assembly.js +51 -22
- package/dist/sdk/history-repair.d.ts +1 -1
- package/dist/sdk/history-repair.js +20 -10
- package/dist/sdk/index.d.ts +1 -0
- package/dist/sdk/index.js +3 -2
- package/dist/sdk/learnings.d.ts +4 -0
- package/dist/sdk/learnings.js +7 -4
- package/dist/sdk/lifecycle/close.js +4 -3
- package/dist/sdk/lifecycle/create.js +43 -19
- package/dist/sdk/linked-artifacts.js +21 -31
- package/dist/sdk/merge/reconcile.js +3 -16
- package/dist/sdk/notes.d.ts +4 -0
- package/dist/sdk/notes.js +2 -2
- package/dist/sdk/query/next.d.ts +6 -0
- package/dist/sdk/query/next.js +7 -2
- package/dist/sdk/runtime-input.js +5 -2
- package/dist/sdk/runtime.d.ts +6 -6
- package/dist/sdk/runtime.js +8 -8
- package/dist/sdk/test/entry.d.ts +1 -1
- package/dist/sdk/test/entry.js +5 -9
- package/dist/sdk/test/execution.d.ts +3 -0
- package/dist/sdk/test/execution.js +54 -13
- package/docs/COMMANDS.md +4 -3
- package/docs/CONTEXT_RECOVERY_PRIMITIVES.md +67 -0
- package/docs/MERGE_SAFETY.md +23 -10
- package/docs/OUTPUT_TOKEN_ACCOUNTING.md +20 -7
- package/docs/README.md +1 -0
- package/docs/RELEASING.md +9 -1
- package/docs/SDK.md +12 -0
- package/docs/SDK_CONTEXT_INTEGRITY.md +12 -1
- package/docs/SDK_RUNTIME_BOUNDARIES.md +10 -0
- package/docs/TESTING.md +6 -2
- package/docs/agent-task-token-baseline.json +97 -11
- package/docs/agent-task-transcripts.json +211 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +3 -3
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +13 -4
- package/docs/performance/cli-transport-overhead.md +10 -2
- package/marketplace.json +2 -2
- package/package.json +8 -8
- 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 +297 -36
- package/dist/cli-bundle/chunks/chunk-MFNTKMTI.js +0 -13
- package/dist/cli-bundle/chunks/chunk-OS27HHBN.js +0 -35
- package/dist/cli-bundle/chunks/chunk-QTO7USTH.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2AGZ5BRT.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-AQ5IYEZZ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-XDPYBQCF.js +0 -156
- package/dist/cli-bundle/focused-chunks/chunk-Y5A7SJJ7.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-YHWHX6YY.js +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="e04a91fa-4625-50fd-9bfd-c712126baf0d")}catch(e){}}();
|
|
3
3
|
import { RelationshipGraph, } from "../relationships.js";
|
|
4
|
-
import { isExternalDependencySourceKind } from "../dependency-provenance.js";
|
|
4
|
+
import { isExternalDependencyReference, isExternalDependencySourceKind, } from "../dependency-provenance.js";
|
|
5
5
|
import { analyzeHierarchyIntegrity, } from "./hierarchy-integrity.js";
|
|
6
6
|
import { resolveWorkspaceRelationshipKindRegistry } from "./workspace-relationship-kind-registry.js";
|
|
7
7
|
export { resolveWorkspaceRelationshipKindRegistry } from "./workspace-relationship-kind-registry.js";
|
|
@@ -22,6 +22,25 @@ export function normalizeDependencyGraphTarget(target) {
|
|
|
22
22
|
? undefined
|
|
23
23
|
: normalized;
|
|
24
24
|
}
|
|
25
|
+
/** Return whether edge provenance assigns a normalized target to the external graph namespace. */
|
|
26
|
+
function isExternalGraphReference(target, sourceKind, externalAllowed = true) {
|
|
27
|
+
const normalized = normalizeDependencyReferenceTarget(target);
|
|
28
|
+
return (externalAllowed &&
|
|
29
|
+
(isExternalDependencySourceKind(sourceKind) ||
|
|
30
|
+
(normalized !== undefined && isExternalDependencyReference(normalized))));
|
|
31
|
+
}
|
|
32
|
+
/** Build a namespace-aware reference identity: local ids are case-folded while external locators retain case. */
|
|
33
|
+
function dependencyReferenceIdentityKey(target, sourceKind) {
|
|
34
|
+
return isExternalGraphReference(target, sourceKind)
|
|
35
|
+
? `external\u0000${target}`
|
|
36
|
+
: `local\u0000${target.toLowerCase()}`;
|
|
37
|
+
}
|
|
38
|
+
/** Resolve one normalized edge target through the namespace selected by its provenance. */
|
|
39
|
+
function resolveGraphReferenceTarget(target, sourceKind, canonicalIds, externalGraphIds) {
|
|
40
|
+
return isExternalGraphReference(target, sourceKind)
|
|
41
|
+
? externalGraphIds.get(target)
|
|
42
|
+
: canonicalIds.get(target.toLowerCase());
|
|
43
|
+
}
|
|
25
44
|
/** Compare text case-insensitively with an exact-spelling deterministic tie-breaker. */
|
|
26
45
|
function compareCaseFoldedText(left, right) {
|
|
27
46
|
const normalizedLeft = left.toLowerCase();
|
|
@@ -45,7 +64,7 @@ function countDependencyRowIdentities(item) {
|
|
|
45
64
|
const kind = typeof legacyDependency.kind === "string"
|
|
46
65
|
? legacyDependency.kind
|
|
47
66
|
: "related";
|
|
48
|
-
const key = `${kind}\u0000${target.
|
|
67
|
+
const key = `${kind}\u0000${dependencyReferenceIdentityKey(target, legacyDependency.source_kind)}`;
|
|
49
68
|
const existing = occurrences.get(key);
|
|
50
69
|
if (existing)
|
|
51
70
|
existing.count += 1;
|
|
@@ -94,7 +113,9 @@ function decodeOrderingStorageContradiction(item, blocker, dependency, isTermina
|
|
|
94
113
|
if (typeof dependency !== "object" || dependency === null)
|
|
95
114
|
return undefined;
|
|
96
115
|
const target = normalizeDependencyReferenceTarget(dependency.id);
|
|
97
|
-
if (!target ||
|
|
116
|
+
if (!target ||
|
|
117
|
+
dependencyReferenceIdentityKey(target, dependency.source_kind) !==
|
|
118
|
+
dependencyReferenceIdentityKey(blocker))
|
|
98
119
|
return undefined;
|
|
99
120
|
const definition = registry.resolve(typeof dependency.kind === "string" ? dependency.kind : "related");
|
|
100
121
|
if (definition?.ordering !== true ||
|
|
@@ -151,9 +172,11 @@ export function collectDanglingDependencyReferences(items, isTerminal = (status)
|
|
|
151
172
|
const safeItems = items.filter((item) => typeof item?.id === "string" && item.id.trim().length > 0);
|
|
152
173
|
const knownIds = new Set(safeItems.map((item) => item.id.trim().toLowerCase()));
|
|
153
174
|
const rows = new Map();
|
|
154
|
-
const addReference = (item, target, kind, source) => {
|
|
175
|
+
const addReference = (item, target, kind, source, externalAllowed) => {
|
|
155
176
|
const normalized = normalizeDependencyReferenceTarget(target);
|
|
156
|
-
if (!normalized ||
|
|
177
|
+
if (!normalized ||
|
|
178
|
+
knownIds.has(normalized.toLowerCase()) ||
|
|
179
|
+
isExternalGraphReference(normalized, undefined, externalAllowed)) {
|
|
157
180
|
return;
|
|
158
181
|
}
|
|
159
182
|
const row = {
|
|
@@ -168,8 +191,8 @@ export function collectDanglingDependencyReferences(items, isTerminal = (status)
|
|
|
168
191
|
rows.set(`${row.holder_id}::${row.target_id}::${row.kind}::${row.source}`, row);
|
|
169
192
|
};
|
|
170
193
|
for (const item of safeItems) {
|
|
171
|
-
addReference(item, item.parent, "parent", "parent");
|
|
172
|
-
addReference(item, item.blocked_by, "blocked_by", "blocked_by");
|
|
194
|
+
addReference(item, item.parent, "parent", "parent", false);
|
|
195
|
+
addReference(item, item.blocked_by, "blocked_by", "blocked_by", true);
|
|
173
196
|
for (const dependency of item.dependencies ?? []) {
|
|
174
197
|
// Public SDK callers may supply legacy or JSON-decoded payloads that do
|
|
175
198
|
// not yet satisfy the current structured dependency contract.
|
|
@@ -182,7 +205,7 @@ export function collectDanglingDependencyReferences(items, isTerminal = (status)
|
|
|
182
205
|
}
|
|
183
206
|
addReference(item, legacyDependency.id, typeof legacyDependency.kind === "string"
|
|
184
207
|
? legacyDependency.kind
|
|
185
|
-
: "related", "dependency");
|
|
208
|
+
: "related", "dependency", true);
|
|
186
209
|
}
|
|
187
210
|
}
|
|
188
211
|
const sorted = [...rows.values()].sort((left, right) => left.holder_id.localeCompare(right.holder_id) ||
|
|
@@ -213,15 +236,21 @@ export function collectMissingDependencyTargetIds(dangling) {
|
|
|
213
236
|
export function collectExternalDependencyTargetIds(items) {
|
|
214
237
|
const targets = new Map();
|
|
215
238
|
for (const item of items) {
|
|
239
|
+
const scalarBlocker = normalizeDependencyGraphTarget(item.blocked_by);
|
|
240
|
+
if (scalarBlocker &&
|
|
241
|
+
isExternalGraphReference(scalarBlocker) &&
|
|
242
|
+
!targets.has(scalarBlocker)) {
|
|
243
|
+
targets.set(scalarBlocker, scalarBlocker);
|
|
244
|
+
}
|
|
216
245
|
for (const dependency of item.dependencies ?? []) {
|
|
217
246
|
if (typeof dependency !== "object" ||
|
|
218
247
|
dependency === null ||
|
|
219
|
-
!
|
|
248
|
+
!isExternalGraphReference(dependency.id, dependency.source_kind)) {
|
|
220
249
|
continue;
|
|
221
250
|
}
|
|
222
|
-
const id =
|
|
223
|
-
if (id && !targets.has(id
|
|
224
|
-
targets.set(id
|
|
251
|
+
const id = normalizeDependencyGraphTarget(dependency.id);
|
|
252
|
+
if (id && !targets.has(id)) {
|
|
253
|
+
targets.set(id, id);
|
|
225
254
|
}
|
|
226
255
|
}
|
|
227
256
|
}
|
|
@@ -230,7 +259,7 @@ export function collectExternalDependencyTargetIds(items) {
|
|
|
230
259
|
const hierarchyIntegrityByAssembly = new WeakMap();
|
|
231
260
|
/** Read the hierarchy analysis paired with an assembly created by this module. */
|
|
232
261
|
export function getWorkspaceHierarchyIntegrity(assembly) {
|
|
233
|
-
return assembly.hierarchyIntegrity ?? hierarchyIntegrityByAssembly.get(assembly);
|
|
262
|
+
return (assembly.hierarchyIntegrity ?? hierarchyIntegrityByAssembly.get(assembly));
|
|
234
263
|
}
|
|
235
264
|
/** Count raw dependency rows that use a registered compatibility alias instead of its canonical kind. */
|
|
236
265
|
export function collectLegacyDependencyAliasCounts(items, registry = resolveWorkspaceRelationshipKindRegistry()) {
|
|
@@ -274,7 +303,7 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
|
|
|
274
303
|
while (usedGraphIds.has(graphId.toLowerCase())) {
|
|
275
304
|
graphId = `external:${graphId}`;
|
|
276
305
|
}
|
|
277
|
-
externalGraphIds.set(id
|
|
306
|
+
externalGraphIds.set(id, graphId);
|
|
278
307
|
usedGraphIds.add(graphId.toLowerCase());
|
|
279
308
|
}
|
|
280
309
|
const graphItems = safeItems.map((item) => {
|
|
@@ -287,9 +316,7 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
|
|
|
287
316
|
const target = normalizeDependencyGraphTarget(dependency.id);
|
|
288
317
|
if (!target)
|
|
289
318
|
return [];
|
|
290
|
-
const targetId =
|
|
291
|
-
? externalGraphIds.get(target.toLowerCase())
|
|
292
|
-
: canonicalIds.get(target.toLowerCase());
|
|
319
|
+
const targetId = resolveGraphReferenceTarget(target, dependency.source_kind, canonicalIds, externalGraphIds);
|
|
293
320
|
return [
|
|
294
321
|
{
|
|
295
322
|
id: targetId,
|
|
@@ -301,7 +328,9 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
|
|
|
301
328
|
id: item.id.trim(),
|
|
302
329
|
...(parent ? { parent: canonicalIds.get(parent.toLowerCase()) } : {}),
|
|
303
330
|
...(blocker
|
|
304
|
-
? {
|
|
331
|
+
? {
|
|
332
|
+
blocked_by: resolveGraphReferenceTarget(blocker, undefined, canonicalIds, externalGraphIds),
|
|
333
|
+
}
|
|
305
334
|
: {}),
|
|
306
335
|
dependencies,
|
|
307
336
|
};
|
|
@@ -312,7 +341,7 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
|
|
|
312
341
|
...graphItems,
|
|
313
342
|
...missingIds.map((id) => ({ id })),
|
|
314
343
|
...externalIds.map((id) => ({
|
|
315
|
-
id: externalGraphIds.get(id
|
|
344
|
+
id: externalGraphIds.get(id),
|
|
316
345
|
})),
|
|
317
346
|
], relationshipRegistry),
|
|
318
347
|
details: [
|
|
@@ -330,7 +359,7 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
|
|
|
330
359
|
status: "missing",
|
|
331
360
|
})),
|
|
332
361
|
...externalIds.map((id) => ({
|
|
333
|
-
id: externalGraphIds.get(id
|
|
362
|
+
id: externalGraphIds.get(id),
|
|
334
363
|
title: `[external] ${id}`,
|
|
335
364
|
status: "external",
|
|
336
365
|
})),
|
|
@@ -346,4 +375,4 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
|
|
|
346
375
|
return assembly;
|
|
347
376
|
}
|
|
348
377
|
//# sourceMappingURL=assembly.js.map
|
|
349
|
-
//# debugId=
|
|
378
|
+
//# debugId=e04a91fa-4625-50fd-9bfd-c712126baf0d
|
|
@@ -83,7 +83,7 @@ export interface MergeReceiptProofResult {
|
|
|
83
83
|
/** Whether exact receipt identity, path, field, and value-hash evidence proves the snapshot. */
|
|
84
84
|
trusted: boolean;
|
|
85
85
|
/** Stable explanation for the trust decision. */
|
|
86
|
-
reason: "
|
|
86
|
+
reason: "trusted_merge_driver_hash_evidence" | "git_workspace_unavailable" | "item_path_unavailable" | "no_item_receipts" | "no_receipt_set_proves_snapshot";
|
|
87
87
|
/** Exact receipt identities accepted as proof; empty when proof is refused. */
|
|
88
88
|
receipt_ids: string[];
|
|
89
89
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements the pm history repair 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]="04dbdc08-ad98-543f-96dc-fde635bae92e")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "./environment/tracker-preflight.js";
|
|
9
9
|
import { realpath } from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
@@ -27,7 +27,7 @@ import { listAllItemMetadataWithBody, readLocatedItem, } from "../core/store/ite
|
|
|
27
27
|
import { resolvePmRoot } from "../core/store/paths.js";
|
|
28
28
|
import { readSettings } from "../core/store/settings.js";
|
|
29
29
|
import { resolveHistorySubject } from "./history-redact.js";
|
|
30
|
-
import { summarizeMergeReceipt, } from "./merge/receipts.js";
|
|
30
|
+
import { inspectMergeReceiptEvidence, summarizeMergeReceipt, } from "./merge/receipts.js";
|
|
31
31
|
import { listInvalidProvenanceHistoryStreamIds, normalizeInvalidHistoryProvenance, } from "./governance/provenance-health.js";
|
|
32
32
|
function replayFieldValue(document, field) {
|
|
33
33
|
return field === "body"
|
|
@@ -148,8 +148,6 @@ async function canonicalRealPath(value) {
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
async function verifyReceiptAgainstSnapshot(params) {
|
|
151
|
-
if (params.receipt.evidence_source !== "clone_local")
|
|
152
|
-
return null;
|
|
153
151
|
const receiptPath = await canonicalRealPath(path.resolve(params.gitWorkspaceRoot, params.receipt.item_path));
|
|
154
152
|
if (receiptPath !== params.currentPath)
|
|
155
153
|
return null;
|
|
@@ -159,11 +157,11 @@ async function verifyReceiptAgainstSnapshot(params) {
|
|
|
159
157
|
...params.receipt.union_fields,
|
|
160
158
|
...params.receipt.decisions.map((decision) => decision.field),
|
|
161
159
|
]),
|
|
162
|
-
].sort(
|
|
160
|
+
].sort();
|
|
163
161
|
const hashes = params.receipt.merged_field_hashes;
|
|
164
162
|
if (!hashes || declaredFields.length === 0)
|
|
165
163
|
return null;
|
|
166
|
-
const hashFields = Object.keys(hashes).sort(
|
|
164
|
+
const hashFields = Object.keys(hashes).sort();
|
|
167
165
|
if (declaredFields.length !== hashFields.length ||
|
|
168
166
|
declaredFields.some((field, index) => field !== hashFields[index])) {
|
|
169
167
|
return null;
|
|
@@ -214,7 +212,7 @@ async function verifyMergeReceiptProof(params) {
|
|
|
214
212
|
reconciliationFields.every((field) => trustedFields.has(field))))) {
|
|
215
213
|
return {
|
|
216
214
|
trusted: true,
|
|
217
|
-
reason: "
|
|
215
|
+
reason: "trusted_merge_driver_hash_evidence",
|
|
218
216
|
receipt_ids: trustedReceipts.map(({ receipt }) => receipt.id),
|
|
219
217
|
};
|
|
220
218
|
}
|
|
@@ -225,7 +223,18 @@ async function verifyMergeReceiptProof(params) {
|
|
|
225
223
|
};
|
|
226
224
|
}
|
|
227
225
|
async function resolveHistoryRepairMergeEvidence(params) {
|
|
228
|
-
const
|
|
226
|
+
const requestedReceiptIds = new Set(params.options.mergeReceiptProof?.receipts
|
|
227
|
+
.filter((receipt) => receipt.item_id === params.subjectId)
|
|
228
|
+
.map((receipt) => receipt.id) ?? []);
|
|
229
|
+
const authoritativeReceiptEvidence = params.options.mergeReceiptProof
|
|
230
|
+
? await inspectMergeReceiptEvidence(params.options.mergeReceiptProof.gitWorkspaceRoot ?? process.cwd(), {
|
|
231
|
+
includeReconciled: true,
|
|
232
|
+
includeLossless: true,
|
|
233
|
+
pmRoot: params.pmRoot,
|
|
234
|
+
})
|
|
235
|
+
: undefined;
|
|
236
|
+
const subjectMergeReceipts = authoritativeReceiptEvidence?.receipts.filter((receipt) => receipt.item_id === params.subjectId &&
|
|
237
|
+
requestedReceiptIds.has(receipt.id)) ?? [];
|
|
229
238
|
const mergeReceiptProof = params.options.mergeReceiptProof
|
|
230
239
|
? await verifyMergeReceiptProof({
|
|
231
240
|
proof: {
|
|
@@ -244,7 +253,7 @@ async function resolveHistoryRepairMergeEvidence(params) {
|
|
|
244
253
|
params.options.force !== true) {
|
|
245
254
|
throw new PmCliError(`Merge receipt evidence for ${params.subjectId} does not prove the exact item snapshot (${mergeReceiptProof.reason}).`, EXIT_CODE.CONFLICT, {
|
|
246
255
|
code: "merge_reconcile_receipt_evidence_untrusted",
|
|
247
|
-
required: "Use clone-local
|
|
256
|
+
required: "Use authoritative clone-local or durable receipt evidence whose canonical path, declared fields, and merged-value hashes match the current item, or review the mismatch and rerun with --force.",
|
|
248
257
|
recovery: { suggested_retry: "pm merge reconcile --dry-run" },
|
|
249
258
|
});
|
|
250
259
|
}
|
|
@@ -405,6 +414,7 @@ export async function runHistoryRepair(id, options, global) {
|
|
|
405
414
|
: undefined;
|
|
406
415
|
const { mergeReceiptProof, effectiveAuditContext } = await resolveHistoryRepairMergeEvidence({
|
|
407
416
|
options,
|
|
417
|
+
pmRoot,
|
|
408
418
|
subjectId: subject.id,
|
|
409
419
|
itemReplayContext,
|
|
410
420
|
reconciliation,
|
|
@@ -581,4 +591,4 @@ export async function runHistoryRepairAll(options, global) {
|
|
|
581
591
|
};
|
|
582
592
|
}
|
|
583
593
|
//# sourceMappingURL=history-repair.js.map
|
|
584
|
-
//# debugId=
|
|
594
|
+
//# debugId=04dbdc08-ad98-543f-96dc-fde635bae92e
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -118,6 +118,7 @@ export * from "./query/item-filter-options.js";
|
|
|
118
118
|
export * from "./query/parsers.js";
|
|
119
119
|
export * from "./output.js";
|
|
120
120
|
export * from "./output-contracts.js";
|
|
121
|
+
export * from "./agent/task-transcript-contracts.js";
|
|
121
122
|
export * from "./relationship-analytics.js";
|
|
122
123
|
export * from "./relationship-context.js";
|
|
123
124
|
export * from "./relationship-history.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]="ea1845ab-34f5-5a1c-ad49-ac81495c1840")}catch(e){}}();
|
|
8
8
|
export { PM_COMMAND_CAPABILITY_CONTRACTS, PM_COMMAND_VISIBILITY_CONTRACTS, PM_MCP_PROMPT_CONTRACTS, PM_MCP_RESOURCE_CONTRACTS, PM_MCP_TOOL_COMMAND_CONTRACTS, listPmCommandsForFamily, listPmCommandsForTier, listPmMcpToolsForProfile, renderPmCommandVisibilityMarkdown, resolvePmCommandCapabilityFamily, resolvePmCommandVisibilityTier, } from "./agent-capability-contracts.js";
|
|
9
9
|
export * from "./mcp/protocol.js";
|
|
10
10
|
export * from "./mcp/interactions.js";
|
|
@@ -115,6 +115,7 @@ export * from "./query/item-filter-options.js";
|
|
|
115
115
|
export * from "./query/parsers.js";
|
|
116
116
|
export * from "./output.js";
|
|
117
117
|
export * from "./output-contracts.js";
|
|
118
|
+
export * from "./agent/task-transcript-contracts.js";
|
|
118
119
|
export * from "./relationship-analytics.js";
|
|
119
120
|
export * from "./relationship-context.js";
|
|
120
121
|
export * from "./relationship-history.js";
|
|
@@ -175,4 +176,4 @@ export * from "./governance.js";
|
|
|
175
176
|
export * from "./query.js";
|
|
176
177
|
export * from "./testing.js";
|
|
177
178
|
//# sourceMappingURL=index.js.map
|
|
178
|
-
//# debugId=
|
|
179
|
+
//# debugId=ea1845ab-34f5-5a1c-ad49-ac81495c1840
|
package/dist/sdk/learnings.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export interface LearningsCommandOptions {
|
|
|
22
22
|
limit?: string;
|
|
23
23
|
/** Return complete learning history after a mutation instead of a bounded receipt. */
|
|
24
24
|
fullHistory?: boolean;
|
|
25
|
+
/** Append only when no learning has the same resolved author and text. */
|
|
26
|
+
ifAbsent?: boolean;
|
|
25
27
|
/** Value that configures or reports author for this contract. */
|
|
26
28
|
author?: string;
|
|
27
29
|
/** Human-readable explanation suitable for logs and agent-facing output. */
|
|
@@ -49,6 +51,8 @@ export interface LearningsResult {
|
|
|
49
51
|
mutation_receipt?: AnnotationMutationReceipt;
|
|
50
52
|
/** Declares whether older learnings were withheld from a mutation response. */
|
|
51
53
|
omission_receipt?: AnnotationOmissionReceipt;
|
|
54
|
+
/** Whether a requested mutation changed persisted state. */
|
|
55
|
+
changed?: boolean;
|
|
52
56
|
}
|
|
53
57
|
/** Implements run learnings for the public runtime surface of this module. */
|
|
54
58
|
export declare function runLearnings(id: string, options: LearningsCommandOptions, global: GlobalOptions): Promise<LearningsResult>;
|
package/dist/sdk/learnings.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="972816c9-b407-5b89-a744-249c9771451f")}catch(e){}}();
|
|
3
3
|
import { parseAnnotationTextInput, resolveAnnotationInput, runAnnotationCommand, } from "./annotations.js";
|
|
4
4
|
/** Implements run learnings for the public runtime surface of this module. */
|
|
5
5
|
export async function runLearnings(id, options, global) {
|
|
@@ -11,11 +11,14 @@ export async function runLearnings(id, options, global) {
|
|
|
11
11
|
deleteOp: "learning_delete",
|
|
12
12
|
parseText: (raw) => parseAnnotationTextInput(raw),
|
|
13
13
|
createEntry: (entry) => entry,
|
|
14
|
-
bypassOwnershipConflict: Boolean(options.edit === undefined &&
|
|
14
|
+
bypassOwnershipConflict: Boolean(options.edit === undefined &&
|
|
15
|
+
options.delete === undefined &&
|
|
15
16
|
options.ownershipAppendBypass),
|
|
16
17
|
conflictGuidance: {
|
|
17
18
|
required: "For an approved append-only handoff on another owner's item, use the package-provided ownership bypass before considering --force.",
|
|
18
|
-
examples: [
|
|
19
|
+
examples: [
|
|
20
|
+
'pm learnings pm-a1b2 --add "review learning" --author "reviewer" --force',
|
|
21
|
+
],
|
|
19
22
|
nextSteps: [
|
|
20
23
|
"Use an installed package's narrow append-only ownership bypass when available.",
|
|
21
24
|
"Use --force only when an ownership override is explicitly approved.",
|
|
@@ -24,4 +27,4 @@ export async function runLearnings(id, options, global) {
|
|
|
24
27
|
});
|
|
25
28
|
}
|
|
26
29
|
//# sourceMappingURL=learnings.js.map
|
|
27
|
-
//# debugId=
|
|
30
|
+
//# debugId=972816c9-b407-5b89-a744-249c9771451f
|
|
@@ -4,11 +4,12 @@
|
|
|
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]="9f28f7d8-993b-5201-b606-d1eab0c3ff5c")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
9
9
|
import { toItemRecord, isTerminalStatus, resolveItemTypeRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, PmCliError, buildItemNotFoundError, listAllItemMetadataLight, locateItem, mutateItem, readLocatedItem, resolvePmRoot, readSettings, resolveAuthor, resolveIsoOrRelative, shouldCompletePlanOnClose, getActiveExtensionRegistrations, } from "../runtime-primitives.js";
|
|
10
10
|
import { collectBlockedByIds, indexBlockedByIds } from "../actionability.js";
|
|
11
11
|
import { applyTerminalOrderingPolicy, requireTerminalReason, } from "../lifecycle-policy.js";
|
|
12
|
+
import { nowIso } from "../../core/shared/time.js";
|
|
12
13
|
import { renderPmCommand } from "../command-line.js";
|
|
13
14
|
const CLOSE_VALIDATION_FIELDS = [
|
|
14
15
|
{ key: "resolution", label: "resolution (--resolution)" },
|
|
@@ -415,7 +416,7 @@ export async function closeItem(id, closeReasonText, options, global) {
|
|
|
415
416
|
// informational note instead of the warn/strict validation warning.
|
|
416
417
|
const trackerItems = await listAllItemMetadataLight(pmRoot, settings.item_format, typeToFolder, undefined, settings.schema);
|
|
417
418
|
const activeChildIds = findActiveChildIds(trackerItems, located.id, statusRegistry);
|
|
418
|
-
const closedAt =
|
|
419
|
+
const closedAt = nowIso();
|
|
419
420
|
const completedAt = options.completedAt === undefined
|
|
420
421
|
? closedAt
|
|
421
422
|
: resolveIsoOrRelative(options.completedAt, new Date(closedAt), "completed-at");
|
|
@@ -457,4 +458,4 @@ export function runClose(id, closeReasonText, options, global) {
|
|
|
457
458
|
return closeItem(id, closeReasonText, options, global);
|
|
458
459
|
}
|
|
459
460
|
//# sourceMappingURL=close.js.map
|
|
460
|
-
//# debugId=
|
|
461
|
+
//# debugId=9f28f7d8-993b-5201-b606-d1eab0c3ff5c
|
|
@@ -4,9 +4,9 @@
|
|
|
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]="c9bfbfd4-3d34-5fa7-b264-6bf9ed5f7f81")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "../environment/tracker-preflight.js";
|
|
9
|
-
import { resolveMutationStdinTokenFields } from "../../core/item/parse.js";
|
|
9
|
+
import { assertNoAmbiguousBareCommaEntry, looksLikeStructuredKeyValueEntry, resolveMutationStdinTokenFields, } from "../../core/item/parse.js";
|
|
10
10
|
import { removeFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, generateItemId, normalizeItemId, canonicalDocument, normalizeItemMetadata, serializeItemDocument, assertParentReferenceIsNotSelf, isPlaceholderReferenceToken, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, assertNoUnknownCsvKeys, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, shouldResolveMutationStdinTokens, transferMutationStdinTokenPolicy, resolvePriority, getFocusedItem, normalizeStatusInput, isTerminalStatus, 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, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
|
|
11
11
|
import { requireTerminalReasonWithRecovery } from "../lifecycle-policy.js";
|
|
12
12
|
import { evaluateSimilarityGovernance, similarityAdvisoryWarnings, } from "../similarity.js";
|
|
@@ -19,7 +19,7 @@ import { normalizeRiskInput, normalizeSeverityInput, parseConfidenceInput, parse
|
|
|
19
19
|
import { applyLegacyNoneCollectionNormalizers, createLegacyNoneCollectionNormalizers, assertNoLegacyNoneToken, assertNoLegacyNoneTokens, isLegacyNoneToken, } from "./legacy-none-tokens.js";
|
|
20
20
|
import { suggestNextLifecycleTransition, } from "./lifecycle-transitions.js";
|
|
21
21
|
import { parseLinkedTestAssertionEqualsMap, parseLinkedTestAssertionGteMap, parseLinkedTestBoolean, parseLinkedTestContextMode, parseLinkedTestEnvClear, parseLinkedTestEnvSet, parseLinkedTestMinLines, parseLinkedTestRegexList, parseLinkedTestStringList, parseLinkedTestWorkspaceContextMode, } from "../test/parsers.js";
|
|
22
|
-
import {
|
|
22
|
+
import { STRUCTURED_LINKED_TEST_KEYS, normalizeStructuredLinkedTestEntry, } from "../test/entry.js";
|
|
23
23
|
import { attachLinkedTestMutationProvenance } from "../test/trust.js";
|
|
24
24
|
import { COMMON_UNSET_FIELD_DEFINITIONS_AFTER_AUTHOR, COMMON_UNSET_FIELD_DEFINITIONS_BEFORE_AUTHOR, parseCommandUnsetTargets, resolveRuntimeUnsetFieldDefinition, } from "./shared-unset-fields.js";
|
|
25
25
|
import { ensureEnumValue } from "./recurrence-parsers.js";
|
|
@@ -202,13 +202,7 @@ function normalizeDependencyKindInput(raw) {
|
|
|
202
202
|
: raw;
|
|
203
203
|
}
|
|
204
204
|
function looksLikeStructuredEntry(raw, keys) {
|
|
205
|
-
if (raw
|
|
206
|
-
return true;
|
|
207
|
-
}
|
|
208
|
-
const keyPattern = keys
|
|
209
|
-
.map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
|
|
210
|
-
.join("|");
|
|
211
|
-
if (new RegExp(`^(?:[-*+]\\s+)?(?:${keyPattern})\\s*[:=]`, "i").test(raw)) {
|
|
205
|
+
if (looksLikeStructuredKeyValueEntry(raw, keys)) {
|
|
212
206
|
return true;
|
|
213
207
|
}
|
|
214
208
|
// A first-key typo (e.g. `bogus=v,id=pm-2`) must still be parsed so the unknown
|
|
@@ -281,6 +275,7 @@ export function parseFiles(raw) {
|
|
|
281
275
|
const values = raw.map((entry) => {
|
|
282
276
|
const trimmedEntry = entry.trim();
|
|
283
277
|
const isStructured = looksLikeStructuredEntry(trimmedEntry, LINKED_ARTIFACT_SEED_KEYS);
|
|
278
|
+
assertNoAmbiguousBareCommaEntry(trimmedEntry, "--file", "file path", isStructured);
|
|
284
279
|
const kv = isStructured
|
|
285
280
|
? parseCsvKv(entry, "--file")
|
|
286
281
|
: { path: trimmedEntry };
|
|
@@ -305,7 +300,9 @@ export function parseTests(raw) {
|
|
|
305
300
|
assertNoLegacyNoneTokens(raw, "--test", "Use --clear-tests to clear linked tests.");
|
|
306
301
|
const values = raw.map((entry) => {
|
|
307
302
|
const trimmedEntry = entry.trim();
|
|
308
|
-
const
|
|
303
|
+
const isStructured = looksLikeStructuredEntry(trimmedEntry, STRUCTURED_LINKED_TEST_KEYS);
|
|
304
|
+
assertNoAmbiguousBareCommaEntry(trimmedEntry, "--test", "test command", isStructured);
|
|
305
|
+
const kv = isStructured
|
|
309
306
|
? normalizeStructuredLinkedTestEntry(parseCsvKv(entry, "--test"), "--test")
|
|
310
307
|
: { command: trimmedEntry };
|
|
311
308
|
const command = parseOptionalString(kv.command);
|
|
@@ -1331,6 +1328,19 @@ function assertNoCreateFieldUnsetConflicts(registeredItemFieldValues, runtimeCre
|
|
|
1331
1328
|
}
|
|
1332
1329
|
}
|
|
1333
1330
|
/** 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. */
|
|
1331
|
+
/** Truthful empty-collection alternatives for strict required create fields. */
|
|
1332
|
+
const CLEAR_FLAG_BY_REQUIRED_CREATE_FLAG = {
|
|
1333
|
+
"--comment": "--clear-comments",
|
|
1334
|
+
"--dep": "--clear-deps",
|
|
1335
|
+
"--doc": "--clear-docs",
|
|
1336
|
+
"--event": "--clear-events",
|
|
1337
|
+
"--file": "--clear-files",
|
|
1338
|
+
"--learning": "--clear-learnings",
|
|
1339
|
+
"--note": "--clear-notes",
|
|
1340
|
+
"--reminder": "--clear-reminders",
|
|
1341
|
+
"--test": "--clear-tests",
|
|
1342
|
+
"--type-option": "--clear-type-options",
|
|
1343
|
+
};
|
|
1334
1344
|
function assertNoMissingRequiredCreateOptions(params) {
|
|
1335
1345
|
const { combinedMissingFlags, typeDefinition, missingRequiredCreateFlags, missingRequiredTypeOptionKeys, openStatus, type, createMode, missingRequiredRuntimeFields, } = params;
|
|
1336
1346
|
if (combinedMissingFlags.length === 0) {
|
|
@@ -1359,12 +1369,12 @@ function assertNoMissingRequiredCreateOptions(params) {
|
|
|
1359
1369
|
].join(" ");
|
|
1360
1370
|
const nextSteps = [
|
|
1361
1371
|
`Run "pm create --help --type ${type}" for type-aware required option guidance.`,
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1372
|
+
...combinedMissingFlags
|
|
1373
|
+
.filter((flag) => flag === "--title")
|
|
1374
|
+
.map(() => 'Title can also be passed as the first positional argument (example: pm create "Your title" --type ' +
|
|
1365
1375
|
type +
|
|
1366
|
-
").")
|
|
1367
|
-
|
|
1376
|
+
")."),
|
|
1377
|
+
];
|
|
1368
1378
|
if (createMode === "strict") {
|
|
1369
1379
|
nextSteps.push('For staged onboarding, retry with "--create-mode progressive".');
|
|
1370
1380
|
if (SCHEDULE_CREATE_PRESET_TYPES.has(type)) {
|
|
@@ -1374,21 +1384,35 @@ function assertNoMissingRequiredCreateOptions(params) {
|
|
|
1374
1384
|
if (runtimeFieldSyntax.length > 0) {
|
|
1375
1385
|
nextSteps.push(`Required custom field formats: ${runtimeFieldSyntax.map((field) => field.description).join("; ")}.`);
|
|
1376
1386
|
}
|
|
1387
|
+
const collectionClearFlags = [
|
|
1388
|
+
...new Set(combinedMissingFlags.flatMap((flag) => {
|
|
1389
|
+
const normalizedFlag = flag.split(" ", 1)[0];
|
|
1390
|
+
const clearFlag = CLEAR_FLAG_BY_REQUIRED_CREATE_FLAG[normalizedFlag];
|
|
1391
|
+
return clearFlag ? [clearFlag] : [];
|
|
1392
|
+
})),
|
|
1393
|
+
];
|
|
1394
|
+
if (collectionClearFlags.length > 0) {
|
|
1395
|
+
nextSteps.push(`If the truthful value is an empty collection, use ${collectionClearFlags.join(", ")} instead of inventing metadata.`);
|
|
1396
|
+
}
|
|
1377
1397
|
const errorMessage = combinedMissingFlags.length === 1
|
|
1378
1398
|
? `Missing required option ${combinedMissingFlags[0]} for type "${type}"`
|
|
1379
1399
|
: `Missing required options ${combinedMissingFlags.join(", ")} for type "${type}"`;
|
|
1380
1400
|
throw new PmCliError(errorMessage, EXIT_CODE.USAGE, {
|
|
1381
1401
|
code: "missing_required_option",
|
|
1382
1402
|
required: `Provide all required create options and type options for type "${type}" in one invocation.`,
|
|
1383
|
-
examples: [
|
|
1403
|
+
examples: [
|
|
1404
|
+
...collectionClearFlags.map((flag) => `pm create --type ${type} ${flag} ...`),
|
|
1405
|
+
nextValidExample,
|
|
1406
|
+
],
|
|
1384
1407
|
nextSteps,
|
|
1385
1408
|
recovery: createMode === "strict"
|
|
1386
1409
|
? {
|
|
1387
1410
|
recovery_mode: "compact",
|
|
1388
1411
|
missing_required_fields: combinedMissingFlags,
|
|
1389
1412
|
suggested_flags: [
|
|
1390
|
-
|
|
1413
|
+
...collectionClearFlags,
|
|
1391
1414
|
...combinedMissingFlags,
|
|
1415
|
+
"--create-mode progressive",
|
|
1392
1416
|
],
|
|
1393
1417
|
}
|
|
1394
1418
|
: undefined,
|
|
@@ -1926,4 +1950,4 @@ export const _testOnlyCreateCommand = {
|
|
|
1926
1950
|
typeOptionExampleValue,
|
|
1927
1951
|
};
|
|
1928
1952
|
//# sourceMappingURL=create.js.map
|
|
1929
|
-
//# debugId=
|
|
1953
|
+
//# debugId=c9bfbfd4-3d34-5fa7-b264-6bf9ed5f7f81
|
|
@@ -4,22 +4,21 @@
|
|
|
4
4
|
* Implements the pm linked artifacts 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]="accd0229-6974-5950-8cea-74f517706878")}catch(e){}}();
|
|
8
8
|
import { assertInitializedTracker } from "./environment/tracker-preflight.js";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import fg from "fast-glob";
|
|
12
12
|
import { isFileAbsentError } from "../core/fs/fs-utils.js";
|
|
13
13
|
import { getActiveExtensionRegistrations } from "../core/extensions/index.js";
|
|
14
|
-
import { assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, parseCsvKv, } from "../core/item/parse.js";
|
|
14
|
+
import { assertNoAmbiguousBareCommaEntry, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, parseCsvKv, } from "../core/item/parse.js";
|
|
15
15
|
import { resolveItemTypeRegistry } from "../core/item/type-registry.js";
|
|
16
16
|
import { isRemoteLinkedArtifactReference } from "../core/validate/linked-artifact-reference.js";
|
|
17
17
|
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
18
18
|
import { PmCliError } from "../core/shared/errors.js";
|
|
19
|
-
import { splitCommaList } from "../core/shared/split-comma-list.js";
|
|
20
19
|
import { stableValueEquals } from "../core/shared/serialization.js";
|
|
21
20
|
import { locateItem, mutateItem, readLocatedItem, } from "../core/store/item-store.js";
|
|
22
|
-
import { resolvePmRoot, resolveWorkspaceRoot
|
|
21
|
+
import { resolvePmRoot, resolveWorkspaceRoot } from "../core/store/paths.js";
|
|
23
22
|
import { readSettings } from "../core/store/settings.js";
|
|
24
23
|
import { SCOPE_VALUES } from "../types/index.js";
|
|
25
24
|
import { resolveAuthor } from "../core/shared/author.js";
|
|
@@ -63,7 +62,9 @@ export function looksLikeStructuredPathEntry(raw) {
|
|
|
63
62
|
// leading assignment syntax through the structured-key allowlist so typos
|
|
64
63
|
// and malformed URL-plus-note input remain atomic failures (GH-258,
|
|
65
64
|
// GH-1000).
|
|
66
|
-
const
|
|
65
|
+
const firstCommaIndex = raw.indexOf(",");
|
|
66
|
+
const leadingSegment = raw.slice(0, firstCommaIndex >= 0 ? firstCommaIndex : raw.length);
|
|
67
|
+
const equalsIndex = leadingSegment.indexOf("=");
|
|
67
68
|
if (equalsIndex >= 0 &&
|
|
68
69
|
!/\s/u.test(raw) &&
|
|
69
70
|
(/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(raw) ||
|
|
@@ -71,18 +72,7 @@ export function looksLikeStructuredPathEntry(raw) {
|
|
|
71
72
|
[raw.indexOf("/"), raw.indexOf("\\")].some((separatorIndex) => separatorIndex >= 0 && separatorIndex < equalsIndex))) {
|
|
72
73
|
return false;
|
|
73
74
|
}
|
|
74
|
-
return
|
|
75
|
-
}
|
|
76
|
-
function expandBareCommaSeparatedAddEntries(raw) {
|
|
77
|
-
return raw.flatMap((entry) => {
|
|
78
|
-
const trimmed = entry.trim();
|
|
79
|
-
if (trimmed.length === 0 ||
|
|
80
|
-
looksLikeStructuredPathEntry(trimmed) ||
|
|
81
|
-
!trimmed.includes(",")) {
|
|
82
|
-
return [entry];
|
|
83
|
-
}
|
|
84
|
-
return splitCommaList(trimmed);
|
|
85
|
-
});
|
|
75
|
+
return leadingSegment.includes("=") || looksLikeGenericKeyValueEntry(raw);
|
|
86
76
|
}
|
|
87
77
|
/** Whether a Markdown destination contains only balanced parentheses. */
|
|
88
78
|
function hasBalancedParentheses(value) {
|
|
@@ -136,21 +126,21 @@ export function parseAddEntries(raw, bareNoun) {
|
|
|
136
126
|
if (reference !== undefined)
|
|
137
127
|
return [reference];
|
|
138
128
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
129
|
+
assertNoAmbiguousBareCommaEntry(trimmed, "--add", `${bareNoun} path`, looksLikeStructuredPathEntry(trimmed));
|
|
130
|
+
const kv = looksLikeStructuredPathEntry(trimmed)
|
|
131
|
+
? parseCsvKv(entry, "--add")
|
|
132
|
+
: { path: trimmed };
|
|
133
|
+
assertNoUnknownCsvKeys(kv, "--add", LINKED_ARTIFACT_ADD_KEYS);
|
|
134
|
+
if (!kv.path) {
|
|
135
|
+
throw new PmCliError(`--add requires path=<value> or a bare ${bareNoun} path`, EXIT_CODE.USAGE);
|
|
136
|
+
}
|
|
137
|
+
return [
|
|
138
|
+
{
|
|
149
139
|
path: kv.path,
|
|
150
140
|
scope: ensureScope(kv.scope),
|
|
151
141
|
note: kv.note?.trim() || undefined,
|
|
152
|
-
}
|
|
153
|
-
|
|
142
|
+
},
|
|
143
|
+
];
|
|
154
144
|
});
|
|
155
145
|
}
|
|
156
146
|
/** Implements parse add glob entries for the public runtime surface of this module. */
|
|
@@ -439,7 +429,7 @@ async function buildLinkedArtifactResult(params) {
|
|
|
439
429
|
migrations_applied: params.migrationsApplied && params.migrationsApplied > 0
|
|
440
430
|
? params.migrationsApplied
|
|
441
431
|
: undefined,
|
|
442
|
-
validation: params.options.validatePaths
|
|
432
|
+
validation: params.options.validatePaths || params.changed
|
|
443
433
|
? await validateLinkedPaths(paths, params.workspaceRoot)
|
|
444
434
|
: undefined,
|
|
445
435
|
};
|
|
@@ -538,4 +528,4 @@ export function renameArtifactsResultKey(result, key) {
|
|
|
538
528
|
return out;
|
|
539
529
|
}
|
|
540
530
|
//# sourceMappingURL=linked-artifacts.js.map
|
|
541
|
-
//# debugId=
|
|
531
|
+
//# debugId=accd0229-6974-5950-8cea-74f517706878
|