@unbrained/pm-cli 2026.8.9 → 2026.8.11
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 +142 -80
- package/dist/cli/commander-usage.js +94 -17
- package/dist/cli/error-guidance.d.ts +10 -0
- package/dist/cli/error-guidance.js +76 -25
- package/dist/cli/help-json-payload.js +51 -16
- package/dist/cli/main.js +11 -6
- package/dist/cli/register-assurance.d.ts +8 -0
- package/dist/cli/register-assurance.js +52 -0
- package/dist/cli/register-files-lookup.js +14 -3
- package/dist/cli/register-mutation.js +30 -9
- package/dist/cli/register-operations.js +16 -11
- package/dist/cli-bundle/bundle-manifest.json +163 -163
- package/dist/cli-bundle/chunks/{chunk-RJC7TPF4.js → chunk-2OOU2AFH.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-2RA2YTHJ.js +33 -0
- package/dist/cli-bundle/chunks/chunk-A2SJGHSI.js +3 -0
- package/dist/cli-bundle/chunks/chunk-DSKYD4LG.js +13 -0
- package/dist/cli-bundle/chunks/chunk-HC3GM6YY.js +194 -0
- package/dist/cli-bundle/chunks/chunk-IUNRVDAI.js +2 -0
- package/dist/cli-bundle/chunks/chunk-W7CPZGSB.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-YC3UF2IO.js → chunk-WMEZHCFI.js} +66 -60
- package/dist/cli-bundle/chunks/{chunk-GMX5YOI3.js → chunk-ZU34C3LH.js} +48 -48
- package/dist/cli-bundle/chunks/chunk-ZXOC6HG5.js +5 -0
- package/dist/cli-bundle/chunks/{register-list-query-BUE7PTCU.js → register-list-query-HAUXVUPY.js} +8 -8
- package/dist/cli-bundle/chunks/register-mutation-7Y5U7ABT.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-EQX3DLAZ.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-UQDTNTLJ.js → register-setup-NOCOOWQY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-KNEHLPBF.js → chunk-23FTGO3W.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-6DO4YQWZ.js → chunk-2DL3MRTD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3AYKXMYX.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-4AHEC74N.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-MRWVJ3ZG.js → chunk-4H5IA6AV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-4SV3ZKG3.js +16 -0
- package/dist/cli-bundle/focused-chunks/chunk-55BIB6DV.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-6JW6Z2P5.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-BKPIY34S.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-D4PIWE6D.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-DPO7TEFX.js +31 -0
- package/dist/cli-bundle/focused-chunks/{chunk-3WVHTUAW.js → chunk-E3KCL7AY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-ERAAFLPS.js +153 -0
- package/dist/cli-bundle/focused-chunks/chunk-F6E4JZKG.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-FPSYO5ZG.js +18 -0
- package/dist/cli-bundle/focused-chunks/{chunk-73FIJONU.js → chunk-J5EKAIVD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-KDH5OX3D.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-OJ3LVVIS.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-TL5M2PAY.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-UDAZWT25.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-VABB4L5Y.js +17 -0
- 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 +41 -39
- 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/session/session-state.d.ts +47 -0
- package/dist/core/session/session-state.js +207 -6
- package/dist/core/shared/author.d.ts +8 -2
- package/dist/core/shared/author.js +85 -52
- package/dist/core/shared/errors.d.ts +12 -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/agent/refusal-reachability.d.ts +40 -0
- package/dist/sdk/agent/refusal-reachability.js +72 -0
- package/dist/sdk/agent/subcommand-recovery.d.ts +40 -0
- package/dist/sdk/agent/subcommand-recovery.js +84 -0
- package/dist/sdk/cli-bootstrap.d.ts +9 -1
- package/dist/sdk/cli-bootstrap.js +25 -10
- package/dist/sdk/cli-contracts/commander-mutation-options.js +16 -4
- package/dist/sdk/cli-contracts/completeness.js +13 -3
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.js +3 -2
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +77 -21
- package/dist/sdk/cli-contracts/registration-helpers.js +10 -2
- package/dist/sdk/cli-contracts/runtime-contracts.js +6 -3
- package/dist/sdk/cli-contracts/schemas/assurance-definition.d.ts +513 -0
- package/dist/sdk/cli-contracts/schemas/assurance-definition.js +251 -0
- 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 +96 -4
- package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
- package/dist/sdk/cli-contracts/tool-schema.js +49 -6
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +3 -3
- package/dist/sdk/completion.js +9 -3
- package/dist/sdk/config.js +9 -3
- package/dist/sdk/context/semantic-session-attribution.d.ts +32 -0
- package/dist/sdk/context/semantic-session-attribution.js +83 -0
- 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/core-governance.d.ts +3 -1
- package/dist/sdk/core-governance.js +5 -3
- package/dist/sdk/core.d.ts +1 -1
- package/dist/sdk/core.js +2 -2
- package/dist/sdk/dependency-flag-validation.d.ts +15 -1
- package/dist/sdk/dependency-flag-validation.js +54 -2
- package/dist/sdk/error-code-catalog.d.ts +13 -0
- package/dist/sdk/error-code-catalog.js +35 -2
- package/dist/sdk/extension.js +18 -17
- package/dist/sdk/files.d.ts +11 -0
- package/dist/sdk/files.js +82 -24
- package/dist/sdk/generated-error-code-catalog.js +104 -13
- package/dist/sdk/governance/assurance-action-contracts.d.ts +7 -0
- package/dist/sdk/governance/assurance-action-contracts.js +5 -0
- package/dist/sdk/governance/assurance-action.d.ts +70 -0
- package/dist/sdk/governance/assurance-action.js +198 -0
- package/dist/sdk/governance/assurance-limits.d.ts +7 -0
- package/dist/sdk/governance/assurance-limits.js +11 -0
- package/dist/sdk/governance/assurance-runtime.d.ts +20 -0
- package/dist/sdk/governance/assurance-runtime.js +131 -0
- package/dist/sdk/governance/assurance.d.ts +432 -0
- package/dist/sdk/governance/assurance.js +689 -0
- 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/graph/run.js +8 -3
- package/dist/sdk/index.d.ts +10 -1
- package/dist/sdk/index.js +12 -3
- package/dist/sdk/lifecycle/claim.js +18 -3
- 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/focus.js +13 -3
- package/dist/sdk/lifecycle/plan.js +8 -3
- 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/provenance.d.ts +38 -0
- package/dist/sdk/provenance.js +64 -2
- package/dist/sdk/query/context.d.ts +2 -0
- package/dist/sdk/query/context.js +24 -10
- package/dist/sdk/query/light-metadata.d.ts +3 -0
- package/dist/sdk/query/light-metadata.js +19 -0
- package/dist/sdk/runtime-extended-actions.js +22 -5
- package/dist/sdk/runtime-primitives.d.ts +2 -0
- package/dist/sdk/runtime-primitives.js +4 -2
- package/dist/sdk/runtime.d.ts +8 -1
- package/dist/sdk/runtime.js +37 -28
- 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/telemetry.js +7 -4
- package/dist/sdk/traceability/runtime-files-lookup.d.ts +8 -0
- package/dist/sdk/traceability/runtime-files-lookup.js +33 -0
- package/dist/sdk/traceability/source-traceability.d.ts +102 -0
- package/dist/sdk/traceability/source-traceability.js +293 -0
- package/dist/sdk/workspace-snapshot.d.ts +4 -0
- package/dist/sdk/workspace-snapshot.js +24 -11
- package/dist/types.d.ts +8 -2
- package/dist/types.js +2 -2
- package/docs/AGENT_GUIDE.md +3 -1
- package/docs/ASSURANCE.md +132 -0
- package/docs/COMMANDS.md +8 -5
- package/docs/MERGE_SAFETY.md +7 -5
- package/docs/README.md +3 -5
- package/docs/READ_OUTPUT_CONTRACTS.md +2 -2
- package/docs/RELEASING.md +9 -5
- package/docs/SDK.md +44 -8
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +43 -6
- package/docs/SDK_CONTEXT.md +97 -0
- package/docs/SDK_CONTEXT_INTEGRITY.md +18 -3
- package/docs/SDK_EVIDENCE_TRACEABILITY.md +39 -1
- package/docs/SDK_RUNTIME_BOUNDARIES.md +36 -1
- package/docs/TESTING.md +12 -9
- package/docs/agent-task-token-baseline.json +2 -2
- package/docs/generated/AGENT_COMMAND_SURFACE.md +1 -0
- package/marketplace.json +2 -2
- package/package.json +7 -6
- 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/extensions/templates/index.ts +9 -3
- 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 +1028 -48
- package/dist/cli-bundle/chunks/chunk-2DTCZXSD.js +0 -13
- package/dist/cli-bundle/chunks/chunk-5JO6R4BS.js +0 -3
- package/dist/cli-bundle/chunks/chunk-5KN4DZYV.js +0 -194
- package/dist/cli-bundle/chunks/chunk-EF43KODO.js +0 -2
- 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/chunk-PYO5GZU6.js +0 -5
- package/dist/cli-bundle/chunks/register-mutation-FC3XLVIK.js +0 -20
- 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-C3GCHDSQ.js +0 -31
- 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-U46GQJNY.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-VRXJSGIT.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-XC2ZW3CJ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-ZG54B4XG.js +0 -2
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* Implements the pm update 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]="244583b8-2ffd-5da4-a4d3-46396fb354c0")}catch(e){}}();
|
|
8
8
|
import { pathExists, COMMON_MUTATION_COMMAND_OPTION_KEYS, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, normalizeItemId, toItemRecord, buildInvalidTypeError, assertParentReferenceIsNotSelf, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, applyAcceptanceCriteriaMutations, applyTagRemovals, assertNoUnknownCsvKeys, createStdinTokenResolver, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, splitAcceptanceCriteria, resolvePriority, normalizeStatusInput, isTerminalStatus, collectRuntimeUpdateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, describeAllowedTransitions, evaluateTransition, resolveTypeWorkflows, EXIT_CODE, PmCliError, stableValueEquals, resolveIsoOrRelative, getActiveExtensionRegistrations, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, buildItemNotFoundError, listAllItemMetadataLight, locateItem, mutateItem, readLocatedItem, getSettingsPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
|
|
9
9
|
import { runClose } from "./close.js";
|
|
10
10
|
import { normalizeRiskInput, normalizeSeverityInput, parseConfidenceInput, parseRegressionInput, } from "./metadata-normalizers.js";
|
|
11
11
|
import { applyLegacyNoneCollectionNormalizers, createLegacyNoneCollectionNormalizers, assertNoLegacyNoneToken, assertNoLegacyNoneTokens, isLegacyNoneToken, } from "./legacy-none-tokens.js";
|
|
12
12
|
import { ensureEnumValue as ensureEnum } from "./recurrence-parsers.js";
|
|
13
13
|
import { parseEventEntries, parseReminderEntries, parseTypeOptionEntries, } from "./repeatable-metadata-parsers.js";
|
|
14
|
-
import { assertDependencyEdgesAllowed, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
|
|
14
|
+
import { assertDependencyEdgesAllowed, assertDependencyTargetsResolvable, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
|
|
15
15
|
import { normalizeDependencySeedId, normalizeDependencySourceKind, } from "../dependency-provenance.js";
|
|
16
16
|
import { resolveCanonicalRelationshipKind } from "../relationships.js";
|
|
17
17
|
import { collectNewOrderingCycleWarnings } from "../graph/mutation-advisory.js";
|
|
@@ -392,7 +392,8 @@ function normalizeDependencyKindInput(raw) {
|
|
|
392
392
|
? (resolveCanonicalRelationshipKind(raw) ?? raw.trim())
|
|
393
393
|
: raw;
|
|
394
394
|
}
|
|
395
|
-
|
|
395
|
+
/** Parse dependency additions into their canonical storage representation. */
|
|
396
|
+
export function parseDependencyAdditions(raw, prefix, nowIso, fallbackAuthor) {
|
|
396
397
|
if (!raw) {
|
|
397
398
|
return { additions: [] };
|
|
398
399
|
}
|
|
@@ -917,7 +918,20 @@ function validateLinkedArtifactReplacement(params) {
|
|
|
917
918
|
throw new PmCliError(`${params.replaceFlag} cannot be combined with ${params.clearFlag}`, EXIT_CODE.USAGE);
|
|
918
919
|
}
|
|
919
920
|
}
|
|
920
|
-
|
|
921
|
+
/** Validate mutually exclusive and required update mutation option combinations. */
|
|
922
|
+
export function assertUpdateMutationOptionCombinations(options) {
|
|
923
|
+
const hasAdditiveAcceptanceCriteriaMutation = (options.addAc?.length ?? 0) > 0 || (options.removeAc?.length ?? 0) > 0;
|
|
924
|
+
if (options.acceptanceCriteria !== undefined &&
|
|
925
|
+
hasAdditiveAcceptanceCriteriaMutation) {
|
|
926
|
+
throw new PmCliError("Cannot combine --acceptance-criteria replacement with --add-ac or --remove-ac. Use --remove-ac and --add-ac together for an atomic one-entry repair.", EXIT_CODE.USAGE, {
|
|
927
|
+
code: "acceptance_criteria_mutation_conflict",
|
|
928
|
+
reason: "replacement_and_additive_mutation_combined",
|
|
929
|
+
nextSteps: [
|
|
930
|
+
"Use --acceptance-criteria alone to replace the complete list.",
|
|
931
|
+
"Use --remove-ac <old> --add-ac <new> to repair one criterion without replacing unrelated entries.",
|
|
932
|
+
],
|
|
933
|
+
});
|
|
934
|
+
}
|
|
921
935
|
if (options.replaceDeps === true &&
|
|
922
936
|
(options.dep === undefined || options.dep.length === 0)) {
|
|
923
937
|
throw new PmCliError("--replace-deps requires at least one --dep entry", EXIT_CODE.USAGE);
|
|
@@ -1444,7 +1458,7 @@ function applyTagsAndPlanningMutations(document, context, scalarMutationContext)
|
|
|
1444
1458
|
// concurrent branch edits with disjoint additions merge instead of clobbering
|
|
1445
1459
|
// the whole acceptance_criteria value (tag-API parity). Runs after the scalar
|
|
1446
1460
|
// mutations so composition with a `--ac` replace uses the replaced base.
|
|
1447
|
-
function applyAcceptanceCriteriaAdditiveMutation(document, context, scalarMutationContext
|
|
1461
|
+
function applyAcceptanceCriteriaAdditiveMutation(document, context, scalarMutationContext) {
|
|
1448
1462
|
const addValues = context.options.addAc;
|
|
1449
1463
|
const removeValues = context.options.removeAc;
|
|
1450
1464
|
if (!(Array.isArray(addValues) && addValues.length > 0) &&
|
|
@@ -1452,8 +1466,18 @@ function applyAcceptanceCriteriaAdditiveMutation(document, context, scalarMutati
|
|
|
1452
1466
|
return;
|
|
1453
1467
|
}
|
|
1454
1468
|
const mutation = applyAcceptanceCriteriaMutations(splitAcceptanceCriteria(document.metadata.acceptance_criteria), addValues, removeValues);
|
|
1455
|
-
|
|
1456
|
-
|
|
1469
|
+
if (mutation.unmatchedRemovals.length > 0) {
|
|
1470
|
+
throw new PmCliError(`Acceptance criteria removal did not match: ${mutation.unmatchedRemovals.join(", ")}`, EXIT_CODE.NOT_FOUND, {
|
|
1471
|
+
code: "acceptance_criteria_remove_unmatched",
|
|
1472
|
+
reason: "exact_match_not_found",
|
|
1473
|
+
field: "acceptance_criteria",
|
|
1474
|
+
unmatched: mutation.unmatchedRemovals,
|
|
1475
|
+
why: "Lossless removal fails instead of silently applying the remaining mutations when an exact selector is wrong.",
|
|
1476
|
+
nextSteps: [
|
|
1477
|
+
"Read the current acceptance_criteria value and retry with the exact criterion text.",
|
|
1478
|
+
"Use --acceptance-criteria alone only when replacing the complete list is intentional.",
|
|
1479
|
+
],
|
|
1480
|
+
});
|
|
1457
1481
|
}
|
|
1458
1482
|
const nextValue = mutation.criteria.join("; ");
|
|
1459
1483
|
if (document.metadata.acceptance_criteria === nextValue) {
|
|
@@ -1638,7 +1662,7 @@ function mutateUpdateDocument(document, context) {
|
|
|
1638
1662
|
applyLogCollectionMutations(document, context, changedFields);
|
|
1639
1663
|
applyEvidenceCollectionMutations(document, context, changedFields);
|
|
1640
1664
|
applyTagsAndPlanningMutations(document, context, scalarMutationContext);
|
|
1641
|
-
applyAcceptanceCriteriaAdditiveMutation(document, context, scalarMutationContext
|
|
1665
|
+
applyAcceptanceCriteriaAdditiveMutation(document, context, scalarMutationContext);
|
|
1642
1666
|
applyOwnershipAndIssueMutations(document, context, scalarMutationContext, warnings);
|
|
1643
1667
|
if (context.options.dep !== undefined ||
|
|
1644
1668
|
context.options.depRemove !== undefined ||
|
|
@@ -1669,6 +1693,10 @@ function mutateUpdateDocument(document, context) {
|
|
|
1669
1693
|
const actualChangedFields = [...new Set(changedFields)].filter((field) => field === "body"
|
|
1670
1694
|
? document.body !== beforeBody
|
|
1671
1695
|
: !stableValueEquals(beforeMetadata[field], afterMetadata[field]));
|
|
1696
|
+
if (context.options.acceptanceCriteria !== undefined &&
|
|
1697
|
+
actualChangedFields.includes("acceptance_criteria")) {
|
|
1698
|
+
warnings.push(`acceptance_criteria_replaced:${splitAcceptanceCriteria(beforeMetadata.acceptance_criteria).length}:${splitAcceptanceCriteria(afterMetadata.acceptance_criteria).length}`);
|
|
1699
|
+
}
|
|
1672
1700
|
return { changedFields: actualChangedFields, warnings };
|
|
1673
1701
|
}
|
|
1674
1702
|
/** Implements run update for the public runtime surface of this module. */
|
|
@@ -1701,7 +1729,7 @@ export async function runUpdate(id, options, global) {
|
|
|
1701
1729
|
const unsetTargets = parseUpdateUnsetTargets(options.unset, runtimeFieldRegistry, extensionFieldNames);
|
|
1702
1730
|
const clearOptionKeys = new Set(unsetTargets.optionKeys);
|
|
1703
1731
|
const clearItemMetadataKeys = new Set(unsetTargets.metadataKeys);
|
|
1704
|
-
|
|
1732
|
+
assertUpdateMutationOptionCombinations(options);
|
|
1705
1733
|
applyClearCollectionDefinitions({
|
|
1706
1734
|
definitions: buildClearCollectionDefinitions(options),
|
|
1707
1735
|
options,
|
|
@@ -1715,6 +1743,14 @@ export async function runUpdate(id, options, global) {
|
|
|
1715
1743
|
const nowValue = new Date();
|
|
1716
1744
|
const nowIso = nowValue.toISOString();
|
|
1717
1745
|
const dependencyUpdates = parseDependencyAdditions(options.dep, settings.id_prefix, nowIso, author);
|
|
1746
|
+
const dependencyTargetWarnings = await assertDependencyTargetsResolvable({
|
|
1747
|
+
pmRoot,
|
|
1748
|
+
dependencies: dependencyUpdates.additions,
|
|
1749
|
+
idPrefix: settings.id_prefix,
|
|
1750
|
+
itemFormat: settings.item_format,
|
|
1751
|
+
typeToFolder: typeRegistry.type_to_folder,
|
|
1752
|
+
allowUnresolved: options.allowUnresolvedDeps,
|
|
1753
|
+
});
|
|
1718
1754
|
const dependencyRemovals = parseDependencyRemovals(options.depRemove, settings.id_prefix);
|
|
1719
1755
|
const parsedCommentUpdates = parseLogSeed("--comment", options.comment, nowIso, author);
|
|
1720
1756
|
const commentUpdates = options.ownershipMetadataBypass === true && parsedCommentUpdates.values
|
|
@@ -1837,6 +1873,7 @@ export async function runUpdate(id, options, global) {
|
|
|
1837
1873
|
warnings: [
|
|
1838
1874
|
...workflowTransitionWarnings,
|
|
1839
1875
|
...parentReferenceWarnings,
|
|
1876
|
+
...dependencyTargetWarnings,
|
|
1840
1877
|
...orderingCycleWarnings,
|
|
1841
1878
|
...result.warnings,
|
|
1842
1879
|
],
|
|
@@ -1860,4 +1897,4 @@ export const _testOnlyUpdateCommand = {
|
|
|
1860
1897
|
resolveRuntimeUnsetDefinition: (token, registry) => resolveRuntimeUnsetFieldDefinition(token, "update", registry),
|
|
1861
1898
|
};
|
|
1862
1899
|
//# sourceMappingURL=update.js.map
|
|
1863
|
-
//# debugId=
|
|
1900
|
+
//# debugId=244583b8-2ffd-5da4-a4d3-46396fb354c0
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
export { ITEM_LATEST_TIMESTAMP_FIELDS, ITEM_UNION_COLLECTION_FIELDS, mergeHistoryStreams, mergeItemDocuments, mergeJsonDocuments, mergeRelationshipEventStreams, type HistoryMergeResult, type HistoryMergeStrategy, type ItemDocumentMergeResult, type JsonDocumentMergeResult, type ItemMergeConflictDecision, type MergePreferredSide, type RelationshipStreamMergeResult, } from "./three-way.js";
|
|
10
10
|
export { listMergeReceipts, markMergeReceiptReconciled, runMergeReceiptReport, summarizeMergeReceipt, type MergeDecisionReceipt, type MergeDecisionReceiptSummary, type MergeReceiptReport, } from "./receipts.js";
|
|
11
11
|
export { MERGE_DRIVER_ARTIFACT_VALUES, runMergeDriver, type MergeDriverArtifact, type MergeDriverOptions, type MergeDriverResult, } from "./driver.js";
|
|
12
|
-
export { auditMergeAttributeFence, auditMergeDriverConfiguration, buildMergeAttributePatterns, findGitWorkspaceRoot, PM_GITATTRIBUTES_END, PM_GITATTRIBUTES_START, refreshMergeAttributeFenceIfInstalled, resolveMergeInstallContext, runMergeInstall, type MergeFenceAuditResult, type MergeDriverConfigurationAuditResult, type MergeFenceRefreshOutcome, type MergeInstallOptions, type MergeInstallContextResolution, type MergeInstallResult, } from "./install.js";
|
|
12
|
+
export { auditMergeAttributeFence, auditMergeDriverConfiguration, buildMergeAttributePatterns, findGitWorkspaceRoot, PM_GITATTRIBUTES_END, PM_GITATTRIBUTES_START, PM_GITATTRIBUTES_V2_END, PM_GITATTRIBUTES_V2_START, refreshMergeAttributeFenceIfInstalled, resolveMergeInstallContext, runMergeInstall, type MergeFenceAuditResult, type MergeDriverConfigurationAuditResult, type MergeFenceRefreshOutcome, type MergeInstallOptions, type MergeInstallContextResolution, type MergeInstallResult, } from "./install.js";
|
|
13
13
|
export { runMergeReconcile, type MergeReconcileOptions, type MergeReconcileResult, } from "./reconcile.js";
|
package/dist/sdk/merge/index.js
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
* this module so packages and hosts can reuse the same merge behavior.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!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]="
|
|
10
|
+
!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]="687855bf-7432-5691-a809-1f0406b5d8a8")}catch(e){}}();
|
|
11
11
|
export { ITEM_LATEST_TIMESTAMP_FIELDS, ITEM_UNION_COLLECTION_FIELDS, mergeHistoryStreams, mergeItemDocuments, mergeJsonDocuments, mergeRelationshipEventStreams, } from "./three-way.js";
|
|
12
12
|
export { listMergeReceipts, markMergeReceiptReconciled, runMergeReceiptReport, summarizeMergeReceipt, } from "./receipts.js";
|
|
13
13
|
export { MERGE_DRIVER_ARTIFACT_VALUES, runMergeDriver, } from "./driver.js";
|
|
14
|
-
export { auditMergeAttributeFence, auditMergeDriverConfiguration, buildMergeAttributePatterns, findGitWorkspaceRoot, PM_GITATTRIBUTES_END, PM_GITATTRIBUTES_START, refreshMergeAttributeFenceIfInstalled, resolveMergeInstallContext, runMergeInstall, } from "./install.js";
|
|
14
|
+
export { auditMergeAttributeFence, auditMergeDriverConfiguration, buildMergeAttributePatterns, findGitWorkspaceRoot, PM_GITATTRIBUTES_END, PM_GITATTRIBUTES_START, PM_GITATTRIBUTES_V2_END, PM_GITATTRIBUTES_V2_START, refreshMergeAttributeFenceIfInstalled, resolveMergeInstallContext, runMergeInstall, } from "./install.js";
|
|
15
15
|
export { runMergeReconcile, } from "./reconcile.js";
|
|
16
16
|
//# sourceMappingURL=index.js.map
|
|
17
|
-
//# debugId=
|
|
17
|
+
//# debugId=687855bf-7432-5691-a809-1f0406b5d8a8
|
|
@@ -5,6 +5,10 @@ import { resolveSourceContextWritePolicy } from "../environment/source-context.j
|
|
|
5
5
|
export declare const PM_GITATTRIBUTES_START = "# pm-cli:merge-drivers:start";
|
|
6
6
|
/** Closing marker for the pm-owned merge-driver `.gitattributes` block. */
|
|
7
7
|
export declare const PM_GITATTRIBUTES_END = "# pm-cli:merge-drivers:end";
|
|
8
|
+
/** Opening marker for the versioned fence that older releases leave untouched. */
|
|
9
|
+
export declare const PM_GITATTRIBUTES_V2_START = "# pm-cli:merge-drivers:v2:start";
|
|
10
|
+
/** Closing marker for the versioned fence that older releases leave untouched. */
|
|
11
|
+
export declare const PM_GITATTRIBUTES_V2_END = "# pm-cli:merge-drivers:v2:end";
|
|
8
12
|
/** Documents the merge install options payload exchanged by command, SDK, and package integrations. */
|
|
9
13
|
export interface MergeInstallOptions {
|
|
10
14
|
/** Preview the `.gitattributes` and `git config` changes without writing anything. */
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* mutations refresh the fenced block automatically once it is installed.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
!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]="
|
|
11
|
+
!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]="94d2a7a8-ce00-5689-b2f6-3d4813234b55")}catch(e){}}();
|
|
12
12
|
import { readFile, realpath, writeFile } from "node:fs/promises";
|
|
13
13
|
import { execFile } from "node:child_process";
|
|
14
14
|
import path from "node:path";
|
|
@@ -30,6 +30,10 @@ const execFileAsync = promisify(execFile);
|
|
|
30
30
|
export const PM_GITATTRIBUTES_START = "# pm-cli:merge-drivers:start";
|
|
31
31
|
/** Closing marker for the pm-owned merge-driver `.gitattributes` block. */
|
|
32
32
|
export const PM_GITATTRIBUTES_END = "# pm-cli:merge-drivers:end";
|
|
33
|
+
/** Opening marker for the versioned fence that older releases leave untouched. */
|
|
34
|
+
export const PM_GITATTRIBUTES_V2_START = "# pm-cli:merge-drivers:v2:start";
|
|
35
|
+
/** Closing marker for the versioned fence that older releases leave untouched. */
|
|
36
|
+
export const PM_GITATTRIBUTES_V2_END = "# pm-cli:merge-drivers:v2:end";
|
|
33
37
|
const MERGE_FENCE_LOCK_ID = "merge-fence";
|
|
34
38
|
/**
|
|
35
39
|
* Quote one argument for the shell used by Git merge-driver configuration.
|
|
@@ -235,6 +239,13 @@ export function buildMergeAttributePatterns(trackerRelativeRoot, typeFolders) {
|
|
|
235
239
|
patterns.push(`${quoteGitAttributePattern(`${prefix}extensions/.managed-extensions.json`)} merge=pm-json`);
|
|
236
240
|
return patterns;
|
|
237
241
|
}
|
|
242
|
+
function removeManagedBlock(content, startMarker, endMarker) {
|
|
243
|
+
const start = content.indexOf(startMarker);
|
|
244
|
+
const end = content.indexOf(endMarker);
|
|
245
|
+
return start >= 0 && end > start
|
|
246
|
+
? `${content.slice(0, start)}${content.slice(end + endMarker.length)}`
|
|
247
|
+
: content.replace(startMarker, "").replace(endMarker, "");
|
|
248
|
+
}
|
|
238
249
|
async function reconcileGitattributesBlock(workspaceRoot, patterns, dryRun) {
|
|
239
250
|
const gitattributesPath = path.join(workspaceRoot, ".gitattributes");
|
|
240
251
|
let current = "";
|
|
@@ -247,17 +258,11 @@ async function reconcileGitattributesBlock(workspaceRoot, patterns, dryRun) {
|
|
|
247
258
|
}
|
|
248
259
|
}
|
|
249
260
|
const block = [
|
|
250
|
-
|
|
261
|
+
PM_GITATTRIBUTES_V2_START,
|
|
251
262
|
...patterns,
|
|
252
|
-
|
|
263
|
+
PM_GITATTRIBUTES_V2_END,
|
|
253
264
|
].join("\n");
|
|
254
|
-
const
|
|
255
|
-
const end = current.indexOf(PM_GITATTRIBUTES_END);
|
|
256
|
-
const withoutManagedBlock = start >= 0 && end > start
|
|
257
|
-
? `${current.slice(0, start)}${current.slice(end + PM_GITATTRIBUTES_END.length)}`
|
|
258
|
-
: current
|
|
259
|
-
.replace(PM_GITATTRIBUTES_START, "")
|
|
260
|
-
.replace(PM_GITATTRIBUTES_END, "");
|
|
265
|
+
const withoutManagedBlock = removeManagedBlock(removeManagedBlock(current, PM_GITATTRIBUTES_V2_START, PM_GITATTRIBUTES_V2_END), PM_GITATTRIBUTES_START, PM_GITATTRIBUTES_END);
|
|
261
266
|
const prefix = withoutManagedBlock.trimEnd();
|
|
262
267
|
const next = `${prefix.length > 0 ? `${prefix}\n\n` : ""}${block}\n`;
|
|
263
268
|
if (next === current) {
|
|
@@ -290,7 +295,8 @@ export async function auditMergeAttributeFence(pmRoot, typeFolders) {
|
|
|
290
295
|
const candidate = path.join(directory, ".gitattributes");
|
|
291
296
|
try {
|
|
292
297
|
const raw = await readFile(candidate, "utf8");
|
|
293
|
-
if (raw.includes(
|
|
298
|
+
if (raw.includes(PM_GITATTRIBUTES_V2_START) ||
|
|
299
|
+
raw.includes(PM_GITATTRIBUTES_START)) {
|
|
294
300
|
fenceDirectory = directory;
|
|
295
301
|
fenceContent = raw;
|
|
296
302
|
break;
|
|
@@ -314,11 +320,16 @@ export async function auditMergeAttributeFence(pmRoot, typeFolders) {
|
|
|
314
320
|
};
|
|
315
321
|
}
|
|
316
322
|
const fencePath = path.join(fenceDirectory, ".gitattributes");
|
|
317
|
-
const
|
|
318
|
-
const
|
|
323
|
+
const usesV2 = fenceContent.includes(PM_GITATTRIBUTES_V2_START);
|
|
324
|
+
const startMarker = usesV2
|
|
325
|
+
? PM_GITATTRIBUTES_V2_START
|
|
326
|
+
: PM_GITATTRIBUTES_START;
|
|
327
|
+
const endMarker = usesV2 ? PM_GITATTRIBUTES_V2_END : PM_GITATTRIBUTES_END;
|
|
328
|
+
const start = fenceContent.indexOf(startMarker);
|
|
329
|
+
const end = fenceContent.indexOf(endMarker);
|
|
319
330
|
const committed = end > start
|
|
320
331
|
? fenceContent
|
|
321
|
-
.slice(start +
|
|
332
|
+
.slice(start + startMarker.length, end)
|
|
322
333
|
.split("\n")
|
|
323
334
|
.map((line) => line.trim())
|
|
324
335
|
.filter((line) => line.length > 0)
|
|
@@ -408,7 +419,8 @@ export async function refreshMergeAttributeFenceIfInstalled(pmRoot) {
|
|
|
408
419
|
}
|
|
409
420
|
throw error;
|
|
410
421
|
}
|
|
411
|
-
if (!current.includes(
|
|
422
|
+
if (!current.includes(PM_GITATTRIBUTES_V2_START) &&
|
|
423
|
+
!current.includes(PM_GITATTRIBUTES_START)) {
|
|
412
424
|
return { status: "not_installed", path: gitattributesPath };
|
|
413
425
|
}
|
|
414
426
|
// Re-read after acquiring the dedicated fence lock so every concurrent
|
|
@@ -548,4 +560,4 @@ export async function installMergeFence(options) {
|
|
|
548
560
|
};
|
|
549
561
|
}
|
|
550
562
|
//# sourceMappingURL=install.js.map
|
|
551
|
-
//# debugId=
|
|
563
|
+
//# debugId=94d2a7a8-ce00-5689-b2f6-3d4813234b55
|
|
@@ -25,6 +25,8 @@ export interface MergeDecisionReceipt {
|
|
|
25
25
|
created_at: string;
|
|
26
26
|
/** Reconciliation timestamp, when consumed. */
|
|
27
27
|
reconciled_at?: string;
|
|
28
|
+
/** Whether decision values are recoverable locally or represented by hashes only. */
|
|
29
|
+
value_availability?: "clone_local" | "hash_only";
|
|
28
30
|
}
|
|
29
31
|
/** Privacy-safe receipt summary suitable for committed history context. */
|
|
30
32
|
export interface MergeDecisionReceiptSummary {
|
|
@@ -78,6 +80,7 @@ export declare function writeMergeReceipt(params: {
|
|
|
78
80
|
export declare function listMergeReceipts(cwd: string, options?: {
|
|
79
81
|
includeReconciled?: boolean;
|
|
80
82
|
includeLossless?: boolean;
|
|
83
|
+
pmRoot?: string;
|
|
81
84
|
}): Promise<MergeDecisionReceipt[]>;
|
|
82
85
|
/** Split merge provenance into receipts with discarded values and receipts whose composition was lossless. */
|
|
83
86
|
export declare function partitionMergeReceipts(receipts: MergeDecisionReceipt[]): {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* value for the coordinator that performed the merge.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
!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]="
|
|
10
|
+
!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]="59863597-bf57-5d96-9cba-983443e5b209")}catch(e){}}();
|
|
11
11
|
import { execFile } from "node:child_process";
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
13
|
import { readdir, readFile } from "node:fs/promises";
|
|
@@ -31,6 +31,21 @@ async function resolveReceiptDirectory(cwd) {
|
|
|
31
31
|
return null;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
async function resolveTrackerRootFromItemPath(cwd, itemPath) {
|
|
35
|
+
let directory = path.dirname(path.resolve(cwd, itemPath));
|
|
36
|
+
for (let depth = 0; depth < 12; depth += 1) {
|
|
37
|
+
if (await pathExists(path.join(directory, "settings.json")))
|
|
38
|
+
return directory;
|
|
39
|
+
const parent = path.dirname(directory);
|
|
40
|
+
if (parent === directory)
|
|
41
|
+
break;
|
|
42
|
+
directory = parent;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function durableReceiptDirectory(pmRoot) {
|
|
47
|
+
return path.join(pmRoot, "merge-receipts");
|
|
48
|
+
}
|
|
34
49
|
function receiptFileName(id) {
|
|
35
50
|
return `${id}.json`;
|
|
36
51
|
}
|
|
@@ -47,11 +62,25 @@ export function summarizeMergeReceipt(receipt) {
|
|
|
47
62
|
conflict_resolution: receipt.conflict_resolution,
|
|
48
63
|
decisions: receipt.decisions.map((decision) => ({
|
|
49
64
|
field: decision.field,
|
|
50
|
-
retained_hash:
|
|
51
|
-
|
|
65
|
+
retained_hash: isPrehashedValue(decision.retained) ??
|
|
66
|
+
sha256Hex(stableStringify(decision.retained)),
|
|
67
|
+
discarded_hash: isPrehashedValue(decision.discarded) ??
|
|
68
|
+
sha256Hex(stableStringify(decision.discarded)),
|
|
52
69
|
})),
|
|
53
70
|
};
|
|
54
71
|
}
|
|
72
|
+
function isPrehashedValue(value) {
|
|
73
|
+
if (typeof value !== "object" ||
|
|
74
|
+
value === null ||
|
|
75
|
+
Array.isArray(value) ||
|
|
76
|
+
!("pm_value_hash" in value)) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const hash = value.pm_value_hash;
|
|
80
|
+
return typeof hash === "string" && /^[a-f0-9]{64}$/u.test(hash)
|
|
81
|
+
? hash
|
|
82
|
+
: undefined;
|
|
83
|
+
}
|
|
55
84
|
/** Persist one item-driver outcome in the clone-local Git directory. */
|
|
56
85
|
export async function writeMergeReceipt(params) {
|
|
57
86
|
const directory = await resolveReceiptDirectory(params.cwd);
|
|
@@ -77,18 +106,34 @@ export async function writeMergeReceipt(params) {
|
|
|
77
106
|
decisions: structuredClone(params.decisions),
|
|
78
107
|
state: "pending",
|
|
79
108
|
created_at: nowIso(),
|
|
109
|
+
value_availability: "clone_local",
|
|
80
110
|
};
|
|
81
111
|
await ensureDir(directory);
|
|
82
112
|
await writeFileAtomic(path.join(directory, receiptFileName(receipt.id)), `${JSON.stringify(receipt, null, 2)}\n`);
|
|
113
|
+
const trackerRoot = await resolveTrackerRootFromItemPath(params.cwd, receipt.item_path);
|
|
114
|
+
if (trackerRoot !== null) {
|
|
115
|
+
const durableDirectory = durableReceiptDirectory(trackerRoot);
|
|
116
|
+
const summary = summarizeMergeReceipt(receipt);
|
|
117
|
+
const durableReceipt = {
|
|
118
|
+
...receipt,
|
|
119
|
+
decisions: summary.decisions.map((decision) => ({
|
|
120
|
+
field: decision.field,
|
|
121
|
+
base: null,
|
|
122
|
+
ours: null,
|
|
123
|
+
theirs: null,
|
|
124
|
+
retained: { pm_value_hash: decision.retained_hash },
|
|
125
|
+
discarded: { pm_value_hash: decision.discarded_hash },
|
|
126
|
+
})),
|
|
127
|
+
value_availability: "hash_only",
|
|
128
|
+
};
|
|
129
|
+
await ensureDir(durableDirectory);
|
|
130
|
+
await writeFileAtomic(path.join(durableDirectory, receiptFileName(receipt.id)), `${JSON.stringify(durableReceipt, null, 2)}\n`);
|
|
131
|
+
}
|
|
83
132
|
return receipt;
|
|
84
133
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const directory = await resolveReceiptDirectory(cwd);
|
|
88
|
-
if (directory === null || !(await pathExists(directory))) {
|
|
134
|
+
async function readReceiptsFromDirectory(directory, options) {
|
|
135
|
+
if (!(await pathExists(directory)))
|
|
89
136
|
return [];
|
|
90
|
-
}
|
|
91
|
-
const receipts = [];
|
|
92
137
|
let names;
|
|
93
138
|
try {
|
|
94
139
|
names = await readdir(directory);
|
|
@@ -96,10 +141,10 @@ export async function listMergeReceipts(cwd, options = {}) {
|
|
|
96
141
|
catch {
|
|
97
142
|
return [];
|
|
98
143
|
}
|
|
144
|
+
const receipts = [];
|
|
99
145
|
for (const name of names.sort((left, right) => left.localeCompare(right))) {
|
|
100
|
-
if (!name.endsWith(".json"))
|
|
146
|
+
if (!name.endsWith(".json"))
|
|
101
147
|
continue;
|
|
102
|
-
}
|
|
103
148
|
try {
|
|
104
149
|
const parsed = JSON.parse(await readFile(path.join(directory, name), "utf8"));
|
|
105
150
|
const normalizedReceipt = {
|
|
@@ -109,17 +154,28 @@ export async function listMergeReceipts(cwd, options = {}) {
|
|
|
109
154
|
if (normalizedReceipt.version === 1 &&
|
|
110
155
|
(options.includeReconciled || normalizedReceipt.state === "pending") &&
|
|
111
156
|
(options.includeLossless !== false ||
|
|
112
|
-
|
|
113
|
-
normalizedReceipt.decisions.length > 0))) {
|
|
157
|
+
normalizedReceipt.decisions.length > 0)) {
|
|
114
158
|
receipts.push(normalizedReceipt);
|
|
115
159
|
}
|
|
116
160
|
}
|
|
117
161
|
catch {
|
|
118
|
-
//
|
|
119
|
-
// omitted count once a future schema version adds richer diagnostics.
|
|
162
|
+
// Malformed evidence remains an integrity concern for a future schema.
|
|
120
163
|
}
|
|
121
164
|
}
|
|
122
|
-
return receipts
|
|
165
|
+
return receipts;
|
|
166
|
+
}
|
|
167
|
+
/** Read clone-local receipts with explicit reconciled/lossless classification controls. */
|
|
168
|
+
export async function listMergeReceipts(cwd, options = {}) {
|
|
169
|
+
const directory = await resolveReceiptDirectory(cwd);
|
|
170
|
+
const local = directory === null
|
|
171
|
+
? []
|
|
172
|
+
: await readReceiptsFromDirectory(directory, options);
|
|
173
|
+
const trackerRoot = options.pmRoot ?? path.join(cwd, ".agents", "pm");
|
|
174
|
+
const durable = await readReceiptsFromDirectory(durableReceiptDirectory(trackerRoot), options);
|
|
175
|
+
const receipts = new Map(durable.map((receipt) => [receipt.id, receipt]));
|
|
176
|
+
for (const receipt of local)
|
|
177
|
+
receipts.set(receipt.id, receipt);
|
|
178
|
+
return [...receipts.values()].sort((left, right) => left.created_at.localeCompare(right.created_at));
|
|
123
179
|
}
|
|
124
180
|
/** Split merge provenance into receipts with discarded values and receipts whose composition was lossless. */
|
|
125
181
|
export function partitionMergeReceipts(receipts) {
|
|
@@ -139,6 +195,14 @@ export async function markMergeReceiptReconciled(cwd, receipt) {
|
|
|
139
195
|
return;
|
|
140
196
|
}
|
|
141
197
|
await writeFileAtomic(path.join(directory, receiptFileName(receipt.id)), `${JSON.stringify({ ...receipt, state: "reconciled", reconciled_at: nowIso() }, null, 2)}\n`);
|
|
198
|
+
const trackerRoot = await resolveTrackerRootFromItemPath(cwd, receipt.item_path);
|
|
199
|
+
if (trackerRoot !== null) {
|
|
200
|
+
const durablePath = path.join(durableReceiptDirectory(trackerRoot), receiptFileName(receipt.id));
|
|
201
|
+
if (await pathExists(durablePath)) {
|
|
202
|
+
const durable = JSON.parse(await readFile(durablePath, "utf8"));
|
|
203
|
+
await writeFileAtomic(durablePath, `${JSON.stringify({ ...durable, state: "reconciled", reconciled_at: nowIso() }, null, 2)}\n`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
142
206
|
}
|
|
143
207
|
/** Report pending or historical clone-local merge decisions. */
|
|
144
208
|
export async function runMergeReceiptReport(options) {
|
|
@@ -154,4 +218,4 @@ export async function runMergeReceiptReport(options) {
|
|
|
154
218
|
};
|
|
155
219
|
}
|
|
156
220
|
//# sourceMappingURL=receipts.js.map
|
|
157
|
-
//# debugId=
|
|
221
|
+
//# debugId=59863597-bf57-5d96-9cba-983443e5b209
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Declares machine-readable field-group omissions for bounded command results.
|
|
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]="630b48a7-aa38-529c-a272-14b7c748101c")}catch(e){}}();
|
|
8
8
|
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
9
9
|
import { PmCliError } from "../core/shared/errors.js";
|
|
10
10
|
/** Universal selector for results carrying a {@link ReadRowContract}. */
|
|
@@ -283,11 +283,31 @@ function resolveContextReceipt(result) {
|
|
|
283
283
|
function resolveGetReceipt(result) {
|
|
284
284
|
if (!isRecord(result.item))
|
|
285
285
|
return undefined;
|
|
286
|
-
const
|
|
286
|
+
const item = result.item;
|
|
287
|
+
const itemGroups = [
|
|
288
|
+
"comments",
|
|
289
|
+
"notes",
|
|
290
|
+
"learnings",
|
|
291
|
+
"files",
|
|
292
|
+
"tests",
|
|
293
|
+
"docs",
|
|
294
|
+
"reminders",
|
|
295
|
+
"events",
|
|
296
|
+
];
|
|
297
|
+
const resultGroups = [
|
|
298
|
+
"body",
|
|
299
|
+
"children",
|
|
300
|
+
"claim_state",
|
|
301
|
+
"linked",
|
|
302
|
+
"schedule",
|
|
303
|
+
];
|
|
304
|
+
const groups = ["body", ...itemGroups, ...resultGroups.slice(1)].map((name) => ({
|
|
287
305
|
name,
|
|
288
306
|
restore_with: `--fields ${name}`,
|
|
289
307
|
}));
|
|
290
|
-
return createOutputOmissionReceipt(groups, new Set(groups.flatMap(({ name }) => (
|
|
308
|
+
return createOutputOmissionReceipt(groups, new Set(groups.flatMap(({ name }) => !Object.hasOwn(itemGroups.includes(name) ? item : result, name)
|
|
309
|
+
? []
|
|
310
|
+
: [name])));
|
|
291
311
|
}
|
|
292
312
|
function resolveListOrSearchReceipt(result) {
|
|
293
313
|
if (!isRecord(result.projection))
|
|
@@ -358,4 +378,4 @@ export function attachOutputOmissionReceipt(command, result) {
|
|
|
358
378
|
: { ...disclosedResult, omission_receipt: receipt };
|
|
359
379
|
}
|
|
360
380
|
//# sourceMappingURL=output-projection.js.map
|
|
361
|
-
//# debugId=
|
|
381
|
+
//# debugId=630b48a7-aa38-529c-a272-14b7c748101c
|
package/dist/sdk/provenance.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { HistoryEntry } from "../types.js";
|
|
7
7
|
import { type HarnessSignalDescriptor } from "../core/shared/author.js";
|
|
8
|
+
import type { AgentModelSource } from "../core/shared/author.js";
|
|
8
9
|
/** One declared provenance dimension and the built-in harnesses that can supply it. */
|
|
9
10
|
export interface AgentProvenanceDescriptorCoverage {
|
|
10
11
|
/** Stable provenance dimension name. */
|
|
@@ -36,6 +37,34 @@ export interface AgentProvenanceDimensionCoverage extends AgentModelProvenanceCo
|
|
|
36
37
|
/** Stable provenance dimension being summarized. */
|
|
37
38
|
dimension: string;
|
|
38
39
|
}
|
|
40
|
+
/** Semantic attribution coverage for one harness and role/topic dimension. */
|
|
41
|
+
export interface AgentSemanticAttributionCoverage {
|
|
42
|
+
/** Stable detected harness namespace. */
|
|
43
|
+
harness: string;
|
|
44
|
+
/** Semantic dimension being measured. */
|
|
45
|
+
dimension: "role" | "topic";
|
|
46
|
+
/** History events attributed to the harness. */
|
|
47
|
+
entries: number;
|
|
48
|
+
/** Events carrying a non-empty semantic observation. */
|
|
49
|
+
observed: number;
|
|
50
|
+
/** Observed events grouped by precedence source. */
|
|
51
|
+
by_source: Partial<Record<AgentModelSource, number>>;
|
|
52
|
+
/** Observed fraction across all harness events. */
|
|
53
|
+
coverage: number;
|
|
54
|
+
}
|
|
55
|
+
/** Result of applying a corpus-facing semantic coverage threshold. */
|
|
56
|
+
export interface AgentSemanticAttributionCoverageGate {
|
|
57
|
+
/** Whether every sampled harness/dimension row met the threshold. */
|
|
58
|
+
passed: boolean;
|
|
59
|
+
/** Required observed fraction. */
|
|
60
|
+
minimum_coverage: number;
|
|
61
|
+
/** Required event count before a row participates. */
|
|
62
|
+
minimum_entries: number;
|
|
63
|
+
/** Deterministically ordered coverage rows. */
|
|
64
|
+
rows: AgentSemanticAttributionCoverage[];
|
|
65
|
+
/** Harness/dimension keys that failed the threshold. */
|
|
66
|
+
failures: string[];
|
|
67
|
+
}
|
|
39
68
|
/** One declared or inferred episode group with deterministically nested children. */
|
|
40
69
|
export interface AgentEpisodeGroup {
|
|
41
70
|
/** Stable declared or inferred group key. */
|
|
@@ -68,6 +97,15 @@ export declare function summarizeAgentModelProvenance(entries: readonly Pick<His
|
|
|
68
97
|
* every requested provenance dimension without consulting mutable state.
|
|
69
98
|
*/
|
|
70
99
|
export declare function summarizeAgentProvenance(entries: readonly Pick<HistoryEntry, "agent_harness" | "agent_model" | "agent_provenance">[], dimensions?: readonly string[], minimumExplicitSample?: number): AgentProvenanceDimensionCoverage[];
|
|
100
|
+
/**
|
|
101
|
+
* Measure role/topic availability by harness and precedence source, then apply
|
|
102
|
+
* an explicit ratchet. Empty or synthetic corpora therefore remain useful
|
|
103
|
+
* negative controls instead of silently passing a production coverage gate.
|
|
104
|
+
*/
|
|
105
|
+
export declare function evaluateSemanticAttributionCoverage(entries: readonly Pick<HistoryEntry, "agent_harness" | "agent_provenance">[], options?: {
|
|
106
|
+
minimumCoverage?: number;
|
|
107
|
+
minimumEntries?: number;
|
|
108
|
+
}): AgentSemanticAttributionCoverageGate;
|
|
71
109
|
/**
|
|
72
110
|
* Group immutable history by declared episode keys. Legacy entries fall back
|
|
73
111
|
* to their privacy-safe agent instance, or to a deterministic author cohort.
|