@unbrained/pm-cli 2026.10.24 → 2026.10.25
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 +1 -1
- package/CHANGELOG.md +20 -0
- package/dist/cli/error-guidance.js +2 -2
- package/dist/cli/extension-command-help.js +2 -2
- package/dist/cli/register-history-activity.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +1 -1
- package/dist/cli-bundle/chunks/{chunk-R7KWBFM2.js → chunk-3CYXE6BV.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-444VPGQT.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-YEI4N4A6.js → chunk-4GD6QOP6.js} +21 -21
- package/dist/cli-bundle/chunks/{chunk-HZNFNETE.js → chunk-5ZPT67NJ.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-KGZGXC7T.js → chunk-7C3GCLOO.js} +29 -29
- package/dist/cli-bundle/chunks/{chunk-3VI4XDP2.js → chunk-7T3H24HN.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-MA7SNKYK.js → chunk-EYCVAAIP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-CDR5ES7Q.js → chunk-FNZT4BTE.js} +38 -34
- package/dist/cli-bundle/chunks/{chunk-CNEUJHA4.js → chunk-HMJSFWHK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ZDVTXLA6.js → chunk-LNKPH2DD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Z62RXNHW.js → chunk-MVJGGCGQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3S5FLCG7.js → chunk-O3ZTGRIH.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FASDGYQC.js → chunk-RD6UW3MW.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UY5UHI4I.js → chunk-RLXK2S7P.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-URZB3USE.js → chunk-RQKDANP7.js} +42 -42
- package/dist/cli-bundle/chunks/chunk-TLMXSYJA.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-4PNAUT2E.js → chunk-UI3FD3DW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-VSSHB6XI.js → chunk-VAEB6IUQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TZYQ4JDZ.js → chunk-XYLBOXSH.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-CSE47ZAN.js → chunk-YCCGZHOR.js} +2 -2
- package/dist/cli-bundle/chunks/{indexed-receipt-blobs-XANVELIV.js → indexed-receipt-blobs-47I6KKDO.js} +2 -2
- package/dist/cli-bundle/chunks/{mutation-admission-NVTBZ7DH.js → mutation-admission-747C6IUR.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-2FE6K7FQ.js → register-list-query-COST6KRV.js} +3 -3
- package/dist/cli-bundle/chunks/{register-mutation-KZXQUZUH.js → register-mutation-JZVVJUHY.js} +2 -2
- package/dist/cli-bundle/chunks/register-operations-S4LKLUBJ.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-P3VLCTDY.js → register-setup-3ITZXPOL.js} +2 -2
- package/dist/cli-bundle/chunks/{settlement-hook-YUVCO65H.js → settlement-hook-5IVCF6ZY.js} +2 -2
- package/dist/cli-bundle/chunks/stage-3UUIYROS.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-JYXA4JIP.js → chunk-22727JYL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RVUGTIIU.js → chunk-3FM75SBJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RSEGFZTY.js → chunk-3M5FZCMC.js} +54 -54
- package/dist/cli-bundle/focused-chunks/{chunk-BUZ2Z4P3.js → chunk-46KDJH3K.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-5LBZR6YW.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-SHUPX6G2.js → chunk-74KC7FUQ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-77NU7NPN.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-NX7TVNUM.js → chunk-7DEZT4JN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-ES2NGVHZ.js → chunk-B5JOVH5F.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-HMYDUEQK.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-IVLIUPVV.js +12 -0
- package/dist/cli-bundle/focused-chunks/{chunk-X5YRJMAY.js → chunk-KIIGME23.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-IUAYTD2S.js → chunk-LWJ2X75I.js} +24 -24
- package/dist/cli-bundle/focused-chunks/{chunk-SBJ2IKTH.js → chunk-MT5TYMEU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-7RQOFHMH.js → chunk-NC5HUGHU.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-NI5SG2M2.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZMWLV2CE.js → chunk-QH5KMIYZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-POLMFGPQ.js → chunk-U6HXIF6G.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-6HJCSHBG.js → chunk-URWYYJ7K.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5MKNVJCM.js → chunk-W7MCCFYV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-AGCEWJ27.js → chunk-WMPDY5ZU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-R536272H.js → chunk-Y4JHHY24.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TAHSXKAT.js → chunk-ZYCOMRFT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{indexed-receipt-blobs-FVOA3XMI.js → indexed-receipt-blobs-YCLN2ZZG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{mutation-admission-PB6YFY7S.js → mutation-admission-BQBQXILV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{settlement-hook-2VXEB6PP.js → settlement-hook-XVS6P2XI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/stage-VSIL4MTZ.js +2 -0
- package/dist/cli-bundle/main.js +19 -19
- 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 +15 -15
- 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 +55 -56
- 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 +3 -3
- package/dist/core/diagnostics/remediation.js +1 -1
- package/dist/core/shared/errors.d.ts +13 -0
- package/dist/core/shared/errors.js +1 -1
- package/dist/core/store/settings.js +2 -2
- package/dist/sdk/agent/command-recovery.js +1 -1
- package/dist/sdk/cli-contracts/commander-types.js +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
- package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
- package/dist/sdk/cli-contracts/registration-helpers.d.ts +2 -0
- package/dist/sdk/cli-contracts/registration-helpers.js +2 -2
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
- package/dist/sdk/cli-contracts/tool-option-contracts.js +1 -1
- package/dist/sdk/completion/fish.js +3 -1
- package/dist/sdk/completion/zsh.js +3 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/governance/health-merge-evidence.d.ts +5 -0
- package/dist/sdk/governance/health-merge-evidence.js +1 -1
- package/dist/sdk/governance/health.js +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/merge/history-scalar-rebase.d.ts +9 -0
- package/dist/sdk/merge/history-scalar-rebase.js +2 -0
- package/dist/sdk/merge/ignored-artifacts.d.ts +13 -0
- package/dist/sdk/merge/ignored-artifacts.js +2 -0
- package/dist/sdk/merge/stage.js +1 -1
- package/dist/sdk/merge/three-way.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/activity.d.ts +14 -2
- package/dist/sdk/query/activity.js +1 -1
- package/dist/sdk/query/calendar.d.ts +16 -0
- package/dist/sdk/query/calendar.js +3 -3
- package/dist/sdk/query/context.js +2 -2
- package/dist/sdk/query/get.js +1 -1
- package/dist/sdk/query/list.js +1 -1
- package/dist/sdk/query/search-contracts.js +1 -1
- package/dist/sdk/query/window-pagination.d.ts +20 -0
- package/dist/sdk/query/window-pagination.js +2 -0
- package/dist/sdk/read-output-contracts.js +1 -1
- package/dist/sdk/runtime.d.ts +1 -1
- package/dist/sdk/runtime.js +1 -1
- package/dist/sdk/schema-migration.js +2 -2
- package/dist/sdk/templates.d.ts +7 -1
- package/dist/sdk/templates.js +2 -2
- package/docs/COMMANDS.md +19 -1
- package/docs/EXTENSIONS.md +1 -1
- package/docs/MERGE_SAFETY.md +28 -0
- package/docs/SDK.md +85 -6
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +5 -3
- package/marketplace.json +1 -1
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/extensions/calendar/index.ts +6 -0
- 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/runtime.ts +3 -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-claude/package.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +1 -1
- package/plugins/pm-codex/plugin.json +1 -1
- package/runtime-dependencies.json +1 -1
- package/dist/cli-bundle/chunks/chunk-VPMQEVU6.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-BOCBWNKJ.js +0 -2
- package/dist/cli-bundle/chunks/stage-WRDTMCCF.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-3QYTS4OY.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-CEEOWDB7.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-GXAXDPD4.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-NFFPNMTH.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-XTYEASIY.js +0 -2
- package/dist/cli-bundle/focused-chunks/stage-MQE4PFWT.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f6def6d2-fbf3-55ce-8654-0c4e76d78a2a")}catch{}})();import{cloneEmptyReplayDocument,historyEntriesToRaw,normalizeReplayPatchOps,reanchorHistoryEntries,toReplayDocument,tryApplyReplayPatch}from"../../core/history/replay.js";import jsonPatch from"fast-json-patch";import{canonicalDocument,parseItemDocument,serializeItemDocument}from"../../core/item/item-format.js";import{splitAcceptanceCriteria}from"../../core/item/parse.js";import{normalizeItemFormatVersion,requiredItemFormatVersion}from"../../core/item/item-format-version.js";import{EXIT_CODE}from"../../core/shared/constants.js";import{findFirstMergeConflictMarker}from"../../core/shared/conflict-markers.js";import{PmCliError}from"../../core/shared/errors.js";import{sha256Hex,stableStringify}from"../../core/shared/serialization.js";import{compareTimestampStrings}from"../../core/shared/time.js";const ITEM_SCALAR_MISSING_VALUE=Object.freeze({pm_item_scalar_missing:!0});function isItemScalarMissingValue(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)&&Object.keys(value).length===1&&value.pm_item_scalar_missing===!0}function encodeItemScalarDecisionValue(value){return value===void 0?ITEM_SCALAR_MISSING_VALUE:value}function hashItemScalarDecisionValue(value){return sha256Hex(stableStringify(value===void 0?{pm_item_scalar_presence:"missing"}:{pm_item_scalar_presence:"present",value}))}function parseHistoryJsonl(raw,label){const conflictMarker=findFirstMergeConflictMarker(raw);if(conflictMarker)throw new PmCliError(`History merge input (${label}) contains unresolved conflict markers at line ${conflictMarker.line}. Merge drivers must receive clean per-side versions.`,EXIT_CODE.GENERIC_FAILURE);const entries=[];for(const[index,rawLine]of raw.split(/\r?\n/).entries()){const line=rawLine.trim();if(line)try{const parsed=JSON.parse(line);if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new TypeError("history entry must be an object");entries.push(parsed)}catch{throw new PmCliError(`History merge input (${label}) contains invalid JSON at line ${index+1}.`,EXIT_CODE.GENERIC_FAILURE)}}return entries}function historyEntryIdentity(entry){return stableStringify({ts:entry.ts,author:entry.author,op:entry.op,patch:entry.patch,message:entry.message??null})}function commonHistoryPrefixLength(ours,theirs){const limit=Math.min(ours.length,theirs.length);let shared=0;for(;shared<limit&&historyEntryIdentity(ours[shared])===historyEntryIdentity(theirs[shared]);)shared+=1;return shared}function orderHistoryUnionSuffix(ours,theirs,incoming,oursIdentities){const entries=[...ours,...incoming],positions=new Map(entries.map((entry,index)=>[entry,index])),aliases=new Map(entries.map((entry,index)=>[historyEntryIdentity(entry),index])),successors=entries.map(()=>new Set);for(const branch of[ours,theirs]){const coordinates=branch.map(entry=>positions.get(entry)??aliases.get(historyEntryIdentity(entry)));for(let index=1;index<coordinates.length;index+=1)coordinates[index-1]!==coordinates[index]&&successors[coordinates[index-1]].add(coordinates[index])}const predecessors=entries.map(()=>0);for(const targets of successors)for(const target of targets)predecessors[target]+=1;const ready=entries.map((_,index)=>index).filter(index=>predecessors[index]===0),result=[];for(;ready.length>0;){ready.sort((leftIndex,rightIndex)=>{const left=entries[leftIndex],right=entries[rightIndex],byTs=compareTimestampStrings(left.ts,right.ts),leftIdentity=historyEntryIdentity(left),rightIdentity=historyEntryIdentity(right);return byTs||Number(oursIdentities.has(rightIdentity))-Number(oursIdentities.has(leftIdentity))});const index=ready.shift();result.push(entries[index]);for(const target of successors[index])predecessors[target]-=1,predecessors[target]===0&&ready.push(target)}if(result.length!==entries.length)throw new PmCliError("History union cannot preserve contradictory original branch event orders; leave the file unresolved for manual recovery.",EXIT_CODE.GENERIC_FAILURE);return result}function createHistoryBranchProjection(entries){return{entries,positions:new Map(entries.map((entry,index)=>[historyEntryIdentity(entry),index])),index:-1,document:cloneEmptyReplayDocument()}}function advanceHistoryBranch(state,target){const end=target??state.index;for(;state.index<end;){const applied=tryApplyReplayPatch(state.document,state.entries[state.index+1].patch);if(!applied.ok)throw new PmCliError("History union cannot preserve a patch that does not apply in its original branch.",EXIT_CODE.GENERIC_FAILURE);state.document=applied.document,state.index+=1}return state.document}function advanceOrderedHistoryBranch(state,target){if(target!==void 0&&target>state.index+1)throw new PmCliError("History union cannot attribute multiple original branch events to one semantic identity; preserve the source histories for manual recovery.",EXIT_CODE.GENERIC_FAILURE);return advanceHistoryBranch(state,target)}function historyUnionPatchProjection(ours,theirs,shared){if(shared===0)return;const oursBranch=createHistoryBranchProjection(ours),theirsBranch=createHistoryBranchProjection(theirs),prefix=advanceHistoryBranch(oursBranch,shared-1);advanceHistoryBranch(theirsBranch,shared-1);let position=0;const unionFields=new Set([...ITEM_UNION_COLLECTION_FIELDS,...ITEM_UNION_DELIMITED_FIELDS]);return(entry,current)=>{if(position++<shared)return entry.patch;const identity=historyEntryIdentity(entry),oursState=advanceOrderedHistoryBranch(oursBranch,oursBranch.positions.get(identity)),theirsState=advanceOrderedHistoryBranch(theirsBranch,theirsBranch.positions.get(identity)),scalarPatch=normalizeReplayPatchOps(entry.patch).filter(operation=>{const[root,field]=operation.path.slice(1).split("/");return root!=="metadata"||!unionFields.has(field)}),scalar=tryApplyReplayPatch(current,scalarPatch);if(!scalar.ok)throw new PmCliError("History union cannot rebase a scalar patch onto the merged replay position; leave the file unresolved for manual recovery.",EXIT_CODE.GENERIC_FAILURE);const merged=mergeItemMetadataRecords(prefix.metadata,oursState.metadata,theirsState.metadata,"ours","latest_document_update",String(oursState.metadata.updated_at),String(theirsState.metadata.updated_at)),next=scalar.document;for(const field of unionFields)Object.hasOwn(merged.merged,field)?next.metadata[field]=merged.merged[field]:delete next.metadata[field];const canonical=toReplayDocument({metadata:next.metadata,body:next.body});return jsonPatch.compare(current,canonical)}}function mergeHistoryStreams(baseRaw,oursRaw,theirsRaw){const base=parseHistoryJsonl(baseRaw,"base"),ours=parseHistoryJsonl(oursRaw,"ours"),theirs=parseHistoryJsonl(theirsRaw,"theirs"),creates=[base,ours,theirs].map(entries=>entries.filter(entry=>entry.op==="create"));if(creates[0].length===0&&creates.slice(1).every(entries=>entries.length>0)||creates.some(entries=>entries.length>1)||new Set(creates.flat().map(historyEntryIdentity)).size>1)throw new PmCliError("Duplicate item identity: history contains independent or unproven create events. Preserve both branches and assign distinct item ids before merging.",EXIT_CODE.CONFLICT,{code:"item_identity_conflict"});const shared=commonHistoryPrefixLength(ours,theirs);if(shared===ours.length&&shared===theirs.length)return{merged:historyEntriesToRaw(ours),strategy:"identical",common_entries:shared,entries_from_ours:0,entries_from_theirs:0,entries_total:ours.length,reanchored:!1};if(shared===theirs.length)return{merged:historyEntriesToRaw(ours),strategy:"fast_forward_ours",common_entries:shared,entries_from_ours:ours.length-shared,entries_from_theirs:0,entries_total:ours.length,reanchored:!1};if(shared===ours.length)return{merged:historyEntriesToRaw(theirs),strategy:"fast_forward_theirs",common_entries:shared,entries_from_ours:0,entries_from_theirs:theirs.length-shared,entries_total:theirs.length,reanchored:!1};const oursSuffix=ours.slice(shared),seenIdentities=new Set(oursSuffix.map(historyEntryIdentity)),theirsSuffix=theirs.slice(shared).filter(entry=>!seenIdentities.has(historyEntryIdentity(entry))),mergedSuffix=orderHistoryUnionSuffix(oursSuffix,theirs.slice(shared),theirsSuffix,seenIdentities),reanchored=reanchorHistoryEntries([...ours.slice(0,shared),...mergedSuffix],void 0,{continuousHashSurface:!0,projectPatch:historyUnionPatchProjection(ours,theirs,shared)});if(reanchored.skippedOps>0)throw new PmCliError(`History union cannot preserve ${reanchored.skippedOps} patch operation(s) after deterministic suffix ordering; leave the file unresolved for manual recovery.`,EXIT_CODE.GENERIC_FAILURE);return{merged:historyEntriesToRaw(reanchored.entries),strategy:"union_reanchor",common_entries:shared,entries_from_ours:oursSuffix.length,entries_from_theirs:theirsSuffix.length,entries_total:reanchored.entries.length,reanchored:!0}}function parseRelationshipJsonl(raw,label){const conflictMarker=findFirstMergeConflictMarker(raw);if(conflictMarker)throw new PmCliError(`Relationship merge input (${label}) contains unresolved conflict markers at line ${conflictMarker.line}. Merge drivers must receive clean per-side versions.`,EXIT_CODE.GENERIC_FAILURE);const events=[];for(const[index,rawLine]of raw.split(/\r?\n/).entries()){const line=rawLine.trim();if(!line)continue;let parsed;try{parsed=JSON.parse(line)}catch{throw new PmCliError(`Relationship merge input (${label}) contains invalid JSON at line ${index+1}.`,EXIT_CODE.GENERIC_FAILURE)}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed)||typeof parsed.eventId!="string"||typeof parsed.sequence!="number")throw new PmCliError(`Relationship merge input (${label}) line ${index+1} is not a relationship event (eventId + sequence required).`,EXIT_CODE.GENERIC_FAILURE);events.push(parsed)}return events}function relationshipEventsToRaw(events){return events.length===0?"":`${events.map(event=>JSON.stringify(event)).join(`
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="425ef2aa-56fa-5d06-b8d0-316373ad2433")}catch{}})();import{cloneEmptyReplayDocument,historyEntriesToRaw,normalizeReplayPatchOps,reanchorHistoryEntries,toReplayDocument,tryApplyReplayPatch}from"../../core/history/replay.js";import jsonPatch from"fast-json-patch";import{rebaseHistoryScalarPatch}from"./history-scalar-rebase.js";import{canonicalDocument,parseItemDocument,serializeItemDocument}from"../../core/item/item-format.js";import{splitAcceptanceCriteria}from"../../core/item/parse.js";import{normalizeItemFormatVersion,requiredItemFormatVersion}from"../../core/item/item-format-version.js";import{EXIT_CODE}from"../../core/shared/constants.js";import{findFirstMergeConflictMarker}from"../../core/shared/conflict-markers.js";import{PmCliError}from"../../core/shared/errors.js";import{sha256Hex,stableStringify}from"../../core/shared/serialization.js";import{compareTimestampStrings}from"../../core/shared/time.js";const ITEM_SCALAR_MISSING_VALUE=Object.freeze({pm_item_scalar_missing:!0});function isItemScalarMissingValue(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)&&Object.keys(value).length===1&&value.pm_item_scalar_missing===!0}function encodeItemScalarDecisionValue(value){return value===void 0?ITEM_SCALAR_MISSING_VALUE:value}function hashItemScalarDecisionValue(value){return sha256Hex(stableStringify(value===void 0?{pm_item_scalar_presence:"missing"}:{pm_item_scalar_presence:"present",value}))}function parseHistoryJsonl(raw,label){const conflictMarker=findFirstMergeConflictMarker(raw);if(conflictMarker)throw new PmCliError(`History merge input (${label}) contains unresolved conflict markers at line ${conflictMarker.line}. Merge drivers must receive clean per-side versions.`,EXIT_CODE.GENERIC_FAILURE);const entries=[];for(const[index,rawLine]of raw.split(/\r?\n/).entries()){const line=rawLine.trim();if(line)try{const parsed=JSON.parse(line);if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new TypeError("history entry must be an object");entries.push(parsed)}catch{throw new PmCliError(`History merge input (${label}) contains invalid JSON at line ${index+1}.`,EXIT_CODE.GENERIC_FAILURE)}}return entries}function historyEntryIdentity(entry){return stableStringify({ts:entry.ts,author:entry.author,op:entry.op,patch:entry.patch,message:entry.message??null})}function commonHistoryPrefixLength(ours,theirs){const limit=Math.min(ours.length,theirs.length);let shared=0;for(;shared<limit&&historyEntryIdentity(ours[shared])===historyEntryIdentity(theirs[shared]);)shared+=1;return shared}function orderHistoryUnionSuffix(ours,theirs,incoming,oursIdentities){const entries=[...ours,...incoming],positions=new Map(entries.map((entry,index)=>[entry,index])),aliases=new Map(entries.map((entry,index)=>[historyEntryIdentity(entry),index])),successors=entries.map(()=>new Set);for(const branch of[ours,theirs]){const coordinates=branch.map(entry=>positions.get(entry)??aliases.get(historyEntryIdentity(entry)));for(let index=1;index<coordinates.length;index+=1)coordinates[index-1]!==coordinates[index]&&successors[coordinates[index-1]].add(coordinates[index])}const predecessors=entries.map(()=>0);for(const targets of successors)for(const target of targets)predecessors[target]+=1;const ready=entries.map((_,index)=>index).filter(index=>predecessors[index]===0),result=[];for(;ready.length>0;){ready.sort((leftIndex,rightIndex)=>{const left=entries[leftIndex],right=entries[rightIndex],byTs=compareTimestampStrings(left.ts,right.ts),leftIdentity=historyEntryIdentity(left),rightIdentity=historyEntryIdentity(right);return byTs||Number(oursIdentities.has(rightIdentity))-Number(oursIdentities.has(leftIdentity))});const index=ready.shift();result.push(entries[index]);for(const target of successors[index])predecessors[target]-=1,predecessors[target]===0&&ready.push(target)}if(result.length!==entries.length)throw new PmCliError("History union cannot preserve contradictory original branch event orders; leave the file unresolved for manual recovery.",EXIT_CODE.GENERIC_FAILURE);return result}function createHistoryBranchProjection(entries){return{entries,positions:new Map(entries.map((entry,index)=>[historyEntryIdentity(entry),index])),index:-1,document:cloneEmptyReplayDocument()}}function advanceHistoryBranch(state,target){const end=target??state.index;for(;state.index<end;){const applied=tryApplyReplayPatch(state.document,state.entries[state.index+1].patch);if(!applied.ok)throw new PmCliError("History union cannot preserve a patch that does not apply in its original branch.",EXIT_CODE.GENERIC_FAILURE);state.document=applied.document,state.index+=1}return state.document}function advanceOrderedHistoryBranch(state,target){if(target!==void 0&&target>state.index+1)throw new PmCliError("History union cannot attribute multiple original branch events to one semantic identity; preserve the source histories for manual recovery.",EXIT_CODE.GENERIC_FAILURE);return advanceHistoryBranch(state,target)}function historyUnionPatchProjection(ours,theirs,shared){if(shared===0)return;const oursBranch=createHistoryBranchProjection(ours),theirsBranch=createHistoryBranchProjection(theirs),prefix=advanceHistoryBranch(oursBranch,shared-1);advanceHistoryBranch(theirsBranch,shared-1);let position=0;const unionFields=new Set([...ITEM_UNION_COLLECTION_FIELDS,...ITEM_UNION_DELIMITED_FIELDS]);return(entry,current)=>{if(position++<shared)return entry.patch;const identity=historyEntryIdentity(entry),oursState=advanceOrderedHistoryBranch(oursBranch,oursBranch.positions.get(identity)),theirsState=advanceOrderedHistoryBranch(theirsBranch,theirsBranch.positions.get(identity)),scalarPatch=normalizeReplayPatchOps(entry.patch).filter(operation=>{const[root,field]=operation.path.slice(1).split("/");return root!=="metadata"||!unionFields.has(field)}),oursPosition=oursBranch.positions.get(identity),next=rebaseHistoryScalarPatch(current,scalarPatch,{branch:oursPosition===void 0?"theirs":"ours",line:(oursPosition??theirsBranch.positions.get(identity))+1,op:entry.op}),merged=mergeItemMetadataRecords(prefix.metadata,oursState.metadata,theirsState.metadata,"ours","latest_document_update",String(oursState.metadata.updated_at),String(theirsState.metadata.updated_at));for(const field of unionFields)Object.hasOwn(merged.merged,field)?next.metadata[field]=merged.merged[field]:delete next.metadata[field];const canonical=toReplayDocument({metadata:next.metadata,body:next.body});return jsonPatch.compare(current,canonical)}}function mergeHistoryStreams(baseRaw,oursRaw,theirsRaw){const base=parseHistoryJsonl(baseRaw,"base"),ours=parseHistoryJsonl(oursRaw,"ours"),theirs=parseHistoryJsonl(theirsRaw,"theirs"),creates=[base,ours,theirs].map(entries=>entries.filter(entry=>entry.op==="create"));if(creates[0].length===0&&creates.slice(1).every(entries=>entries.length>0)||creates.some(entries=>entries.length>1)||new Set(creates.flat().map(historyEntryIdentity)).size>1)throw new PmCliError("Duplicate item identity: history contains independent or unproven create events. Preserve both branches and assign distinct item ids before merging.",EXIT_CODE.CONFLICT,{code:"item_identity_conflict"});const shared=commonHistoryPrefixLength(ours,theirs);if(shared===ours.length&&shared===theirs.length)return{merged:historyEntriesToRaw(ours),strategy:"identical",common_entries:shared,entries_from_ours:0,entries_from_theirs:0,entries_total:ours.length,reanchored:!1};if(shared===theirs.length)return{merged:historyEntriesToRaw(ours),strategy:"fast_forward_ours",common_entries:shared,entries_from_ours:ours.length-shared,entries_from_theirs:0,entries_total:ours.length,reanchored:!1};if(shared===ours.length)return{merged:historyEntriesToRaw(theirs),strategy:"fast_forward_theirs",common_entries:shared,entries_from_ours:0,entries_from_theirs:theirs.length-shared,entries_total:theirs.length,reanchored:!1};const oursSuffix=ours.slice(shared),seenIdentities=new Set(oursSuffix.map(historyEntryIdentity)),theirsSuffix=theirs.slice(shared).filter(entry=>!seenIdentities.has(historyEntryIdentity(entry))),mergedSuffix=orderHistoryUnionSuffix(oursSuffix,theirs.slice(shared),theirsSuffix,seenIdentities),reanchored=reanchorHistoryEntries([...ours.slice(0,shared),...mergedSuffix],void 0,{continuousHashSurface:!0,projectPatch:historyUnionPatchProjection(ours,theirs,shared)});if(reanchored.skippedOps>0)throw new PmCliError(`History union cannot preserve ${reanchored.skippedOps} patch operation(s) after deterministic suffix ordering; leave the file unresolved for manual recovery.`,EXIT_CODE.GENERIC_FAILURE);return{merged:historyEntriesToRaw(reanchored.entries),strategy:"union_reanchor",common_entries:shared,entries_from_ours:oursSuffix.length,entries_from_theirs:theirsSuffix.length,entries_total:reanchored.entries.length,reanchored:!0}}function parseRelationshipJsonl(raw,label){const conflictMarker=findFirstMergeConflictMarker(raw);if(conflictMarker)throw new PmCliError(`Relationship merge input (${label}) contains unresolved conflict markers at line ${conflictMarker.line}. Merge drivers must receive clean per-side versions.`,EXIT_CODE.GENERIC_FAILURE);const events=[];for(const[index,rawLine]of raw.split(/\r?\n/).entries()){const line=rawLine.trim();if(!line)continue;let parsed;try{parsed=JSON.parse(line)}catch{throw new PmCliError(`Relationship merge input (${label}) contains invalid JSON at line ${index+1}.`,EXIT_CODE.GENERIC_FAILURE)}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed)||typeof parsed.eventId!="string"||typeof parsed.sequence!="number")throw new PmCliError(`Relationship merge input (${label}) line ${index+1} is not a relationship event (eventId + sequence required).`,EXIT_CODE.GENERIC_FAILURE);events.push(parsed)}return events}function relationshipEventsToRaw(events){return events.length===0?"":`${events.map(event=>JSON.stringify(event)).join(`
|
|
2
2
|
`)}
|
|
3
3
|
`}function renumberRelationshipEvents(events){return events.map((event,index)=>({...event,sequence:index+1}))}function mergeRelationshipEventStreams(baseRaw,oursRaw,theirsRaw){parseRelationshipJsonl(baseRaw,"base");const ours=parseRelationshipJsonl(oursRaw,"ours"),theirs=parseRelationshipJsonl(theirsRaw,"theirs"),limit=Math.min(ours.length,theirs.length);let shared=0;for(;shared<limit&&ours[shared].eventId===theirs[shared].eventId;)shared+=1;if(shared===ours.length&&shared===theirs.length)return{merged:relationshipEventsToRaw(ours),strategy:"identical",common_entries:shared,entries_from_ours:0,entries_from_theirs:0,entries_total:ours.length,reanchored:!1};if(shared===theirs.length)return{merged:relationshipEventsToRaw(ours),strategy:"fast_forward_ours",common_entries:shared,entries_from_ours:ours.length-shared,entries_from_theirs:0,entries_total:ours.length,reanchored:!1};if(shared===ours.length)return{merged:relationshipEventsToRaw(theirs),strategy:"fast_forward_theirs",common_entries:shared,entries_from_ours:0,entries_from_theirs:theirs.length-shared,entries_total:theirs.length,reanchored:!1};const oursSuffix=ours.slice(shared),oursEventIds=new Set(oursSuffix.map(event=>event.eventId)),theirsSuffix=theirs.slice(shared).filter(event=>!oursEventIds.has(event.eventId)),mergedSuffix=[...oursSuffix,...theirsSuffix].sort((left,right)=>{if(left.timestamp!==void 0&&right.timestamp!==void 0){const byTs=compareTimestampStrings(left.timestamp,right.timestamp);if(byTs!==0)return byTs}else{if(left.timestamp===void 0&&right.timestamp!==void 0)return 1;if(left.timestamp!==void 0)return-1}const leftFromOurs=oursEventIds.has(left.eventId),rightFromOurs=oursEventIds.has(right.eventId);return leftFromOurs!==rightFromOurs?Number(rightFromOurs)-Number(leftFromOurs):0}),merged=renumberRelationshipEvents([...ours.slice(0,shared),...mergedSuffix]);return{merged:relationshipEventsToRaw(merged),strategy:"union_reanchor",common_entries:shared,entries_from_ours:oursSuffix.length,entries_from_theirs:theirsSuffix.length,entries_total:merged.length,reanchored:!0}}const ITEM_UNION_COLLECTION_FIELDS=["tags","dependencies","comments","notes","learnings","files","tests","test_runs","docs","reminders","events"],ITEM_UNION_DELIMITED_FIELDS=["acceptance_criteria"],ITEM_LATEST_TIMESTAMP_FIELDS=["updated_at"];function jsonEquals(left,right){return left===void 0||right===void 0?left===void 0&&right===void 0:stableStringify(left)===stableStringify(right)}function unionCollection(base,ours,theirs){const toEntries=value=>Array.isArray(value)?value:[],baseIds=new Set(toEntries(base).map(entry=>stableStringify(entry))),oursEntries=toEntries(ours),oursIds=new Set(oursEntries.map(entry=>stableStringify(entry))),theirsEntries=toEntries(theirs),theirsIds=new Set(theirsEntries.map(entry=>stableStringify(entry))),merged=oursEntries.filter(entry=>{const identity=stableStringify(entry);return!baseIds.has(identity)||theirsIds.has(identity)});for(const entry of theirsEntries){const identity=stableStringify(entry);!oursIds.has(identity)&&!baseIds.has(identity)&&merged.push(entry)}return merged}function linkedTestDefinitionIdentity(value){if(typeof value!="object"||value===null||Array.isArray(value))return stableStringify(value);const{provenance:_provenance,...definition}=value;return stableStringify(definition)}function markMergedLinkedTest(value){if(typeof value!="object"||value===null||Array.isArray(value))return value;const test=value;return test.provenance?{...test,provenance:{...test.provenance,source_kind:"merge_union"}}:{...test,provenance:{source_kind:"merge_union"}}}function unionLinkedTests(base,ours,theirs){const toEntries=value=>Array.isArray(value)?value:[],baseIds=new Set(toEntries(base).map(linkedTestDefinitionIdentity)),oursEntries=toEntries(ours),oursIds=new Set(oursEntries.map(linkedTestDefinitionIdentity)),theirsEntries=toEntries(theirs),theirsIds=new Set(theirsEntries.map(linkedTestDefinitionIdentity)),merged=oursEntries.filter(entry=>{const identity=linkedTestDefinitionIdentity(entry);return!baseIds.has(identity)||theirsIds.has(identity)});for(const entry of theirsEntries){const identity=linkedTestDefinitionIdentity(entry);!oursIds.has(identity)&&!baseIds.has(identity)&&merged.push(markMergedLinkedTest(entry))}return merged}function latestTimestamp(ours,theirs){return compareTimestampStrings(String(ours),String(theirs))>=0?ours:theirs}function mergeScalarThreeWay(base,ours,theirs,preferred){return jsonEquals(ours,theirs)?{value:ours,from_theirs:!1,conflict:!1}:jsonEquals(base,ours)?{value:theirs,from_theirs:!0,conflict:!1}:jsonEquals(base,theirs)?{value:ours,from_theirs:!1,conflict:!1}:{value:preferred==="theirs"?theirs:ours,from_theirs:preferred==="theirs",conflict:!0}}function mergeItemScalarThreeWay(base,ours,theirs,preferred,conflictResolution,oursUpdatedAt,theirsUpdatedAt){const outcome=mergeScalarThreeWay(base,ours,theirs,preferred);if(!outcome.conflict)return{...outcome,conflict:!1};if(conflictResolution==="preferred_side")return{...outcome,resolution_basis:"requested_preference",retained_side:outcome.from_theirs?"theirs":"ours"};const timestampOrder=compareTimestampStrings(oursUpdatedAt,theirsUpdatedAt);if(conflictResolution==="latest_document_update"&×tampOrder!==0){const retainTheirs2=timestampOrder<0;return{value:retainTheirs2?theirs:ours,from_theirs:retainTheirs2,conflict:!0,resolution_basis:"document_updated_at",retained_side:retainTheirs2?"theirs":"ours"}}const retainTheirs=stableStringify(encodeItemScalarDecisionValue(theirs)).localeCompare(stableStringify(encodeItemScalarDecisionValue(ours)))<0;return{value:retainTheirs?theirs:ours,from_theirs:retainTheirs,conflict:!0,resolution_basis:"stable_value_tiebreak",retained_side:retainTheirs?"theirs":"ours"}}function toMetadataRecord(document){return{...document.metadata}}function parseItemMergeSide(raw,label,options){try{const document=canonicalDocument(parseItemDocument(raw,{...options,requireSupportedFormat:!0}),options),reservedField=Object.entries(document.metadata).find(([,value])=>isItemScalarMissingValue(value))?.[0];if(reservedField!==void 0)throw new TypeError(`metadata field ${reservedField} uses the reserved missing-scalar evidence marker`);return document}catch(error){throw error instanceof PmCliError&&error.context?.code==="item_format_version_unsupported"?error:new PmCliError(`Item merge input (${label}) is not a readable item document: ${String(error)}`,EXIT_CODE.GENERIC_FAILURE)}}function mergeItemUnionField(params){if(!params.unionFieldSet.has(params.field))return!1;const union=params.field==="tests"?unionLinkedTests(params.baseValue,params.oursValue,params.theirsValue):params.field==="acceptance_criteria"?unionCollection(splitAcceptanceCriteria(params.baseValue),splitAcceptanceCriteria(params.oursValue),splitAcceptanceCriteria(params.theirsValue)).join("; "):unionCollection(params.baseValue,params.oursValue,params.theirsValue);return params.accumulator.merged[params.field]=union,jsonEquals(union,params.oursValue)||params.accumulator.unionFields.push(params.field),!0}function mergeItemScalarField(params){const outcome=mergeItemScalarThreeWay(params.baseValue,params.oursValue,params.theirsValue,params.preferred,params.conflictResolution,params.oursUpdatedAt,params.theirsUpdatedAt);outcome.value!==void 0&&(params.accumulator.merged[params.field]=outcome.value),outcome.conflict?(params.accumulator.conflictFields.push(params.field),params.accumulator.conflictDecisions.push({field:params.field,base:encodeItemScalarDecisionValue(params.baseValue),ours:encodeItemScalarDecisionValue(params.oursValue),theirs:encodeItemScalarDecisionValue(params.theirsValue),retained:encodeItemScalarDecisionValue(outcome.value),discarded:encodeItemScalarDecisionValue(outcome.from_theirs?params.oursValue:params.theirsValue),retained_side:outcome.retained_side,resolution_basis:outcome.resolution_basis})):outcome.from_theirs&¶ms.accumulator.fieldsFromTheirs.push(params.field)}function mergeItemMetadataRecords(baseRecord,oursRecord,theirsRecord,preferred,conflictResolution,oursUpdatedAt,theirsUpdatedAt){const unionFieldSet=new Set([...ITEM_UNION_COLLECTION_FIELDS,...ITEM_UNION_DELIMITED_FIELDS]),latestFieldSet=new Set(ITEM_LATEST_TIMESTAMP_FIELDS),fieldNames=[...new Set([...Object.keys(oursRecord),...Object.keys(theirsRecord)])].sort((left,right)=>left.localeCompare(right)),accumulator={merged:{},conflictFields:[],fieldsFromTheirs:[],unionFields:[],conflictDecisions:[]};for(const field of fieldNames){const baseValue=baseRecord[field],oursValue=oursRecord[field],theirsValue=theirsRecord[field];if(!mergeItemUnionField({field,baseValue,oursValue,theirsValue,unionFieldSet,accumulator})){if(latestFieldSet.has(field)){accumulator.merged[field]=latestTimestamp(oursValue,theirsValue);continue}mergeItemScalarField({field,baseValue,oursValue,theirsValue,preferred,conflictResolution,oursUpdatedAt,theirsUpdatedAt,accumulator})}}return accumulator}function mergeItemDocuments(baseRaw,oursRaw,theirsRaw,options={}){const preferred=options.preferred??"ours",conflictResolution=options.conflictResolution??"preferred_side",ours=parseItemMergeSide(oursRaw,"ours",options),theirs=parseItemMergeSide(theirsRaw,"theirs",options);if(baseRaw.trim().length===0)throw new PmCliError("Duplicate item identity: add/add item documents have no common ancestor. Preserve both branches and assign distinct item ids before merging.",EXIT_CODE.CONFLICT,{code:"item_identity_conflict",item_id:ours.metadata.id});const base=parseItemMergeSide(baseRaw,"base",options);if(base.metadata.id!==ours.metadata.id||base.metadata.id!==theirs.metadata.id)throw new PmCliError("Duplicate or mismatched item identity: all merge sides must address the common ancestor's item id.",EXIT_CODE.CONFLICT,{code:"item_identity_conflict",item_id:base.metadata.id});const baseRecord=toMetadataRecord(base),oursRecord=toMetadataRecord(ours),theirsRecord=toMetadataRecord(theirs),{merged,conflictFields,fieldsFromTheirs,unionFields,conflictDecisions}=mergeItemMetadataRecords(baseRecord,oursRecord,theirsRecord,preferred,conflictResolution,ours.metadata.updated_at,theirs.metadata.updated_at),bodyOutcome=mergeItemScalarThreeWay(base.body,ours.body,theirs.body,preferred,conflictResolution,ours.metadata.updated_at,theirs.metadata.updated_at);bodyOutcome.conflict?(conflictFields.push("body"),conflictDecisions.push({field:"body",base:encodeItemScalarDecisionValue(base.body),ours:encodeItemScalarDecisionValue(ours.body),theirs:encodeItemScalarDecisionValue(theirs.body),retained:encodeItemScalarDecisionValue(bodyOutcome.value),discarded:encodeItemScalarDecisionValue(bodyOutcome.from_theirs?ours.body:theirs.body),retained_side:bodyOutcome.retained_side,resolution_basis:bodyOutcome.resolution_basis})):bodyOutcome.from_theirs&&fieldsFromTheirs.push("body");const mergedMetadata=merged;return mergedMetadata.pm_format_version=normalizeItemFormatVersion(Math.max(...[base.metadata,ours.metadata,theirs.metadata,mergedMetadata].map(requiredItemFormatVersion))),{merged:serializeItemDocument({metadata:mergedMetadata,body:bodyOutcome.value},options),conflict_fields:conflictFields,fields_from_theirs:fieldsFromTheirs,union_fields:unionFields,conflict_decisions:conflictDecisions,requested_preference:preferred,requested_preference_applied:conflictResolution==="preferred_side",conflict_resolution:conflictResolution}}function isPlainObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function parseJsonSide(raw,label){const conflictMarker=findFirstMergeConflictMarker(raw);if(conflictMarker)throw new PmCliError(`JSON merge input (${label}) contains unresolved conflict markers at line ${conflictMarker.line}.`,EXIT_CODE.GENERIC_FAILURE);if(raw.trim().length!==0)try{return JSON.parse(raw)}catch{throw new PmCliError(`JSON merge input (${label}) is not valid JSON.`,EXIT_CODE.GENERIC_FAILURE)}}function mergeAdditiveJsonArrays(base,ours,theirs){if(!Array.isArray(base)||!Array.isArray(ours)||!Array.isArray(theirs))return null;const countEntries=entries=>{const counts=new Map;for(const entry of entries){const identity=stableStringify(entry);counts.set(identity,(counts.get(identity)??0)+1)}return counts},baseCounts=countEntries(base),oursCounts=countEntries(ours),theirsCounts=countEntries(theirs);for(const[identity,baseCount]of baseCounts)if((oursCounts.get(identity)??0)<baseCount||(theirsCounts.get(identity)??0)<baseCount)return null;const unmatchedOursCounts=new Map(oursCounts),additionsFromTheirs=[];for(const entry of theirs){const identity=stableStringify(entry),unmatchedOursCount=unmatchedOursCounts.get(identity)??0;unmatchedOursCount>0?unmatchedOursCounts.set(identity,unmatchedOursCount-1):additionsFromTheirs.push(entry)}return{merged:[...ours,...additionsFromTheirs],acceptedTheirs:additionsFromTheirs.length>0}}function mergeJsonObjects(base,ours,theirs,preferred,pathPrefix,conflictPaths,pathsFromTheirs){if(!isPlainObject(ours)||!isPlainObject(theirs))return null;const baseObject=isPlainObject(base)?base:{},merged={},keys=[...new Set([...Object.keys(ours),...Object.keys(theirs)])].sort((left,right)=>left.localeCompare(right));for(const key of keys){const childPath=pathPrefix.length>0?`${pathPrefix}.${key}`:key,child=mergeJsonKey(baseObject,ours,theirs,key,preferred,childPath,conflictPaths,pathsFromTheirs);child!==void 0&&(merged[key]=child)}return merged}function mergeJsonValue(base,ours,theirs,preferred,pathPrefix,conflictPaths,pathsFromTheirs){if(jsonEquals(ours,theirs))return ours;const additiveArrayMerge=mergeAdditiveJsonArrays(base,ours,theirs);if(additiveArrayMerge!==null)return additiveArrayMerge.acceptedTheirs&&pathsFromTheirs.push(pathPrefix),additiveArrayMerge.merged;const mergedObject=mergeJsonObjects(base,ours,theirs,preferred,pathPrefix,conflictPaths,pathsFromTheirs);if(mergedObject!==null)return mergedObject;const outcome=mergeScalarThreeWay(base,ours,theirs,preferred);return outcome.conflict?conflictPaths.push(pathPrefix):outcome.from_theirs&&pathsFromTheirs.push(pathPrefix),outcome.value}function mergeJsonKey(base,ours,theirs,key,preferred,childPath,conflictPaths,pathsFromTheirs){const inOurs=Object.prototype.hasOwnProperty.call(ours,key),inTheirs=Object.prototype.hasOwnProperty.call(theirs,key),inBase=Object.prototype.hasOwnProperty.call(base,key);if(inOurs&&inTheirs)return mergeJsonValue(base[key],ours[key],theirs[key],preferred,childPath,conflictPaths,pathsFromTheirs);if(inOurs){if(inBase&&jsonEquals(base[key],ours[key])){pathsFromTheirs.push(childPath);return}return inBase?(conflictPaths.push(childPath),preferred==="theirs"?void 0:ours[key]):ours[key]}if(!(inBase&&jsonEquals(base[key],theirs[key])))return inBase?(conflictPaths.push(childPath),preferred==="theirs"?theirs[key]:void 0):(pathsFromTheirs.push(childPath),theirs[key])}function mergeJsonDocuments(baseRaw,oursRaw,theirsRaw,options={}){const preferred=options.preferred??"ours",base=parseJsonSide(baseRaw,"base"),ours=parseJsonSide(oursRaw,"ours"),theirs=parseJsonSide(theirsRaw,"theirs"),conflictPaths=[],pathsFromTheirs=[],merged=mergeJsonValue(base,ours,theirs,preferred,"",conflictPaths,pathsFromTheirs);return{merged:`${JSON.stringify(merged??null,null,2)}
|
|
4
4
|
`,conflict_paths:conflictPaths,paths_from_theirs:pathsFromTheirs,preferred}}export{ITEM_LATEST_TIMESTAMP_FIELDS,ITEM_SCALAR_MISSING_VALUE,ITEM_UNION_COLLECTION_FIELDS,encodeItemScalarDecisionValue,hashItemScalarDecisionValue,isItemScalarMissingValue,mergeHistoryStreams,mergeItemDocuments,mergeJsonDocuments,mergeRelationshipEventStreams};
|