@unbrained/pm-cli 2026.10.27 → 2026.10.28

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.
Files changed (120) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +23 -0
  3. package/dist/cli/commander-usage.js +2 -2
  4. package/dist/cli/error-guidance.js +2 -2
  5. package/dist/cli-bundle/bundle-manifest.json +1 -1
  6. package/dist/cli-bundle/chunks/chunk-2J7I54MQ.js +2 -0
  7. package/dist/cli-bundle/chunks/{chunk-25MTQAHX.js → chunk-3KMYHYJV.js} +2 -2
  8. package/dist/cli-bundle/chunks/{chunk-UHKN6TJM.js → chunk-7V37RC2L.js} +44 -44
  9. package/dist/cli-bundle/chunks/{chunk-5PTMQBKJ.js → chunk-AHVN4GHF.js} +30 -29
  10. package/dist/cli-bundle/chunks/{chunk-QQYLNHZK.js → chunk-CS7QDSUX.js} +28 -28
  11. package/dist/cli-bundle/chunks/{chunk-34OQP43K.js → chunk-CXUQEZDX.js} +3 -3
  12. package/dist/cli-bundle/chunks/{chunk-X5TMR7KC.js → chunk-D3AIQZXF.js} +2 -2
  13. package/dist/cli-bundle/chunks/{chunk-NNIYQHYT.js → chunk-D6P6IBPN.js} +2 -2
  14. package/dist/cli-bundle/chunks/{chunk-HIX2OMEZ.js → chunk-DKLEDWVW.js} +2 -2
  15. package/dist/cli-bundle/chunks/{chunk-2XUDAQK5.js → chunk-DM3PICGU.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-32QK43XG.js → chunk-E5QBZ4HI.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-H434DKYU.js → chunk-JESLOJD7.js} +2 -2
  18. package/dist/cli-bundle/chunks/{chunk-57YPOOED.js → chunk-LWW4F4G2.js} +2 -2
  19. package/dist/cli-bundle/chunks/{chunk-O3LPT34G.js → chunk-PQLRKFPZ.js} +3 -3
  20. package/dist/cli-bundle/chunks/{chunk-ONC4BBQP.js → chunk-RZQNFHXO.js} +2 -2
  21. package/dist/cli-bundle/chunks/{chunk-ER7RLJW5.js → chunk-TH5KPAN4.js} +2 -2
  22. package/dist/cli-bundle/chunks/{chunk-F26MRQZY.js → chunk-XHONSCLJ.js} +6 -6
  23. package/dist/cli-bundle/chunks/{chunk-EKV5GP6P.js → chunk-YUBUNECD.js} +42 -42
  24. package/dist/cli-bundle/chunks/{chunk-OQOEBWHU.js → chunk-YYD5MNAV.js} +2 -2
  25. package/dist/cli-bundle/chunks/{chunk-Q55KZDNF.js → chunk-ZX3XMTZG.js} +2 -2
  26. package/dist/cli-bundle/chunks/{indexed-receipt-blobs-63WYG2PY.js → indexed-receipt-blobs-LHLE7PSG.js} +2 -2
  27. package/dist/cli-bundle/chunks/{mutation-admission-L3A6FSZ7.js → mutation-admission-GKDKHRTZ.js} +2 -2
  28. package/dist/cli-bundle/chunks/{register-list-query-YSQ7UTFI.js → register-list-query-MHJJUM6M.js} +2 -2
  29. package/dist/cli-bundle/chunks/{register-mutation-6HRXYASW.js → register-mutation-SN425O3R.js} +2 -2
  30. package/dist/cli-bundle/chunks/{register-operations-4O3YOYXF.js → register-operations-EYUIUGPW.js} +2 -2
  31. package/dist/cli-bundle/chunks/{register-setup-3WAXNDMY.js → register-setup-WUZ2ZSMY.js} +2 -2
  32. package/dist/cli-bundle/chunks/{settlement-hook-CRW6PVQK.js → settlement-hook-MN3Y7LVX.js} +2 -2
  33. package/dist/cli-bundle/chunks/{stage-I46WD4EN.js → stage-2FYJGGG3.js} +2 -2
  34. package/dist/cli-bundle/focused-chunks/chunk-3EHVI673.js +2 -0
  35. package/dist/cli-bundle/focused-chunks/{chunk-ZA6AEYIM.js → chunk-46WLWK73.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/{chunk-E5C24MCV.js → chunk-4GN2ZPT5.js} +2 -2
  37. package/dist/cli-bundle/focused-chunks/{chunk-NLZUI234.js → chunk-6L4KKRK7.js} +18 -18
  38. package/dist/cli-bundle/focused-chunks/{chunk-WDKZB3V6.js → chunk-6VDRAJYX.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/{chunk-KTXU5WU6.js → chunk-7SZPZOIC.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-YQKLKRMW.js → chunk-B4ZQJEMT.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/{chunk-J67PFM3O.js → chunk-BZSACRVX.js} +3 -3
  42. package/dist/cli-bundle/focused-chunks/{chunk-Y57A4ZDI.js → chunk-C2GLO7HU.js} +3 -3
  43. package/dist/cli-bundle/focused-chunks/{chunk-R2MTHS2H.js → chunk-DRN4W3YJ.js} +2 -2
  44. package/dist/cli-bundle/focused-chunks/{chunk-TAFMNTA5.js → chunk-F6UQJJYB.js} +2 -2
  45. package/dist/cli-bundle/focused-chunks/{chunk-TGUOEOKP.js → chunk-I4X6AKOO.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/{chunk-SM2KGD4J.js → chunk-IQKLJFJE.js} +2 -2
  47. package/dist/cli-bundle/focused-chunks/{chunk-XK3XMZM4.js → chunk-JTCGDODH.js} +2 -2
  48. package/dist/cli-bundle/focused-chunks/{chunk-HWD63G54.js → chunk-L5GX2FGZ.js} +2 -2
  49. package/dist/cli-bundle/focused-chunks/{chunk-MVY6JDIH.js → chunk-LPWZERVD.js} +11 -11
  50. package/dist/cli-bundle/focused-chunks/{chunk-YW5GHQN2.js → chunk-ML5JIUM6.js} +2 -2
  51. package/dist/cli-bundle/focused-chunks/{chunk-YC6NCPLK.js → chunk-OASYSUOH.js} +16 -16
  52. package/dist/cli-bundle/focused-chunks/{chunk-BH7RE2ZY.js → chunk-ON5WFDCG.js} +2 -2
  53. package/dist/cli-bundle/focused-chunks/{chunk-4TXZBGOR.js → chunk-QUPGBO2L.js} +2 -2
  54. package/dist/cli-bundle/focused-chunks/{chunk-SYL73MEI.js → chunk-R3EA3SDW.js} +3 -3
  55. package/dist/cli-bundle/focused-chunks/{chunk-B266DDBJ.js → chunk-TUN4M757.js} +2 -2
  56. package/dist/cli-bundle/focused-chunks/{chunk-ZH7GTEWL.js → chunk-Z26ZPQH6.js} +2 -2
  57. package/dist/cli-bundle/focused-chunks/{indexed-receipt-blobs-GAFC52LQ.js → indexed-receipt-blobs-5H6RMRTK.js} +2 -2
  58. package/dist/cli-bundle/focused-chunks/{mutation-admission-ENBFMV2X.js → mutation-admission-TM3SVU2O.js} +2 -2
  59. package/dist/cli-bundle/focused-chunks/{settlement-hook-PUYJJDFL.js → settlement-hook-LBVWWSCF.js} +2 -2
  60. package/dist/cli-bundle/focused-chunks/{stage-MAWZTM2H.js → stage-7ZBRX2Q2.js} +2 -2
  61. package/dist/cli-bundle/main.js +21 -21
  62. package/dist/cli-bundle/sdk-authoring.js +1 -1
  63. package/dist/cli-bundle/sdk-contracts.js +1 -1
  64. package/dist/cli-bundle/sdk-core.js +25 -24
  65. package/dist/cli-bundle/sdk-governance.js +1 -1
  66. package/dist/cli-bundle/sdk-graph.js +1 -1
  67. package/dist/cli-bundle/sdk-merge.js +46 -46
  68. package/dist/cli-bundle/sdk-query.js +1 -1
  69. package/dist/cli-bundle/sdk-runtime.js +1 -1
  70. package/dist/cli-bundle/sdk-testing.js +1 -1
  71. package/dist/cli-bundle/sdk.js +11 -11
  72. package/dist/core/item/priority.js +1 -1
  73. package/dist/core/shared/errors.d.ts +2 -0
  74. package/dist/core/shared/errors.js +1 -1
  75. package/dist/core/store/item-store.js +1 -1
  76. package/dist/sdk/agent/command-recovery.d.ts +5 -0
  77. package/dist/sdk/agent/command-recovery.js +1 -1
  78. package/dist/sdk/command-line.d.ts +6 -0
  79. package/dist/sdk/command-line.js +1 -1
  80. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  81. package/dist/sdk/index.d.ts +1 -1
  82. package/dist/sdk/index.js +1 -1
  83. package/dist/sdk/lifecycle/close.js +1 -1
  84. package/dist/sdk/lifecycle/create.js +1 -1
  85. package/dist/sdk/lifecycle/update-many.js +1 -1
  86. package/dist/sdk/lifecycle/update.js +1 -1
  87. package/dist/sdk/public-surface.json +1 -1
  88. package/dist/sdk/query/history.d.ts +4 -0
  89. package/dist/sdk/query/history.js +1 -1
  90. package/dist/sdk/runtime/actions.js +1 -1
  91. package/dist/sdk/runtime.js +1 -1
  92. package/dist/sdk/test/command-resolution.d.ts +5 -0
  93. package/dist/sdk/test/command-resolution.js +3 -0
  94. package/dist/sdk/test/execution.js +2 -2
  95. package/docs/COMMANDS.md +28 -1
  96. package/docs/SDK.md +40 -0
  97. package/docs/TESTING.md +28 -2
  98. package/marketplace.json +1 -1
  99. package/package.json +1 -1
  100. package/packages/pm-beads/package.json +1 -1
  101. package/packages/pm-calendar/package.json +1 -1
  102. package/packages/pm-command-kit/package.json +1 -1
  103. package/packages/pm-digital-twin/package.json +1 -1
  104. package/packages/pm-governance-audit/package.json +1 -1
  105. package/packages/pm-guide-shell/package.json +1 -1
  106. package/packages/pm-kanban/package.json +1 -1
  107. package/packages/pm-lifecycle-hooks/package.json +1 -1
  108. package/packages/pm-linked-test-adapters/package.json +1 -1
  109. package/packages/pm-search-advanced/package.json +1 -1
  110. package/packages/pm-templates/package.json +1 -1
  111. package/packages/pm-todos/package.json +1 -1
  112. package/packages/pm-vcs/package.json +1 -1
  113. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  114. package/plugins/pm-claude/package.json +1 -1
  115. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  116. package/plugins/pm-codex/package.json +1 -1
  117. package/plugins/pm-codex/plugin.json +1 -1
  118. package/runtime-dependencies.json +1 -1
  119. package/dist/cli-bundle/chunks/chunk-XERBUA6A.js +0 -2
  120. package/dist/cli-bundle/focused-chunks/chunk-U4UBQBS7.js +0 -2
@@ -1,2 +1,2 @@
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]="0257ab6d-3ef8-5b98-adfd-c7dabd537c43")}catch{}})();import{PmCliError}from"../shared/errors.js";import{EXIT_CODE}from"../shared/constants.js";const PRIORITY_NAME_TO_VALUE={critical:0,high:1,medium:2,low:3,minimal:4},PRIORITY_NAME_LIST=Object.keys(PRIORITY_NAME_TO_VALUE),PRIORITY_ACCEPTED_FORMS_HINT=`numbers 0..4 (0=critical, 1=high, 2=medium, 3=low, 4=minimal) or names (${PRIORITY_NAME_LIST.join(", ")}), case-insensitive`;function priorityUsageError(raw){return new PmCliError(`Invalid priority "${raw}". Accepted values: ${PRIORITY_ACCEPTED_FORMS_HINT}.`,EXIT_CODE.USAGE)}function resolvePriority(raw){if(typeof raw=="number"){if(Number.isInteger(raw)&&raw>=0&&raw<=4)return raw;throw priorityUsageError(String(raw))}if(typeof raw!="string")throw priorityUsageError(String(raw));const trimmed=raw.trim();if(trimmed.length===0)throw priorityUsageError(raw);const normalizedName=trimmed.toLowerCase();if(Object.prototype.hasOwnProperty.call(PRIORITY_NAME_TO_VALUE,normalizedName))return PRIORITY_NAME_TO_VALUE[normalizedName];if(/^[0-4]$/.test(trimmed))return Number(trimmed);throw priorityUsageError(raw)}export{PRIORITY_ACCEPTED_FORMS_HINT,PRIORITY_NAME_TO_VALUE,resolvePriority};
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]="a59d5b7f-9764-53c5-a014-1119868be8ea")}catch{}})();import{PmCliError}from"../shared/errors.js";import{EXIT_CODE}from"../shared/constants.js";const PRIORITY_NAME_TO_VALUE={critical:0,high:1,medium:2,low:3,minimal:4},PRIORITY_NAME_LIST=Object.keys(PRIORITY_NAME_TO_VALUE),PRIORITY_ACCEPTED_FORMS_HINT=`numbers 0..4 (0=critical, 1=high, 2=medium, 3=low, 4=minimal) or names (${PRIORITY_NAME_LIST.join(", ")}), case-insensitive`;function priorityUsageError(raw){return new PmCliError(`Invalid priority "${raw}". Accepted values: ${PRIORITY_ACCEPTED_FORMS_HINT}.`,EXIT_CODE.USAGE,{code:"invalid_argument_value",field:"priority",value:raw,allowed:["0","1","2","3","4",...PRIORITY_NAME_LIST]})}function resolvePriority(raw){if(typeof raw=="number"){if(Number.isInteger(raw)&&raw>=0&&raw<=4)return raw;throw priorityUsageError(String(raw))}if(typeof raw!="string")throw priorityUsageError(String(raw));const trimmed=raw.trim();if(trimmed.length===0)throw priorityUsageError(raw);const normalizedName=trimmed.toLowerCase();if(Object.prototype.hasOwnProperty.call(PRIORITY_NAME_TO_VALUE,normalizedName))return PRIORITY_NAME_TO_VALUE[normalizedName];if(/^[0-4]$/.test(trimmed))return Number(trimmed);throw priorityUsageError(raw)}export{PRIORITY_ACCEPTED_FORMS_HINT,PRIORITY_NAME_TO_VALUE,resolvePriority};
2
2
  //# sourceMappingURL=priority.js.map
@@ -168,6 +168,8 @@ empty?:boolean;
168
168
  reason?:string;
169
169
  /** Metadata field responsible for a validation failure, when known. */
170
170
  field?:string;
171
+ /** Accepted scalar spellings from the active validation domain, without parsing diagnostic prose. */
172
+ allowed?:string[];
171
173
  /** Original branch coordinates of a scalar patch that cannot safely join a history union. */
172
174
  history_merge?:{
173
175
  /** Side supplying the original event. */
@@ -1,2 +1,2 @@
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]="85f8d656-86eb-52a9-8160-70b60b9da511")}catch{}})();class PmCliError extends Error{exitCode;code;context;constructor(message,exitCode,context={}){super(message),this.name="PmCliError",this.exitCode=exitCode,this.context=context,this.code=context.code}}export{PmCliError};
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]="48da67d7-53a6-5b8e-a73f-58e67cdb9c22")}catch{}})();class PmCliError extends Error{exitCode;code;context;constructor(message,exitCode,context={}){super(message),this.name="PmCliError",this.exitCode=exitCode,this.context=context,this.code=context.code}}export{PmCliError};
2
2
  //# sourceMappingURL=errors.js.map
@@ -1,2 +1,2 @@
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]="1b26ef78-61ae-53d1-a0c8-f6cf9d3794a0")}catch{}})();import fs from"node:fs/promises";import{buildDeletedItemError}from"../history/tombstone.js";import{normalizeHistoryOperationForWrite}from"../history/operation-contract.js";import{enforceWorkflowMutation}from"../policy/workflow-policy-store.js";import{recordItemMetadataEnumeration}from"./item-metadata-read-work.js";import{advanceItemMutationPreconditions,assertItemMutationPreconditions,itemMutationPreconditionHistoryContext}from"./item-mutation-precondition.js";import{checkpointMutationHistoryContext}from"../checkpoint/mutation-context.js";import path from"node:path";import{getActiveExtensionRegistrations,projectAfterCommandItemSnapshot,recordAfterCommandAffectedItem,runActiveOnReadHooks,runActiveBeforeMutationHooks,runActiveOnWriteHooks,runActiveServiceOverride}from"../extensions/index.js";import{collectRegisteredItemFieldNames}from"../extensions/item-fields.js";import{EMPTY_CANONICAL_DOCUMENT,EXIT_CODE,TYPE_TO_FOLDER}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{levenshteinDistanceWithinLimit}from"../shared/levenshtein.js";import{appendHistoryEntry,createHistoryEntry}from"../history/history.js";import{enforceHistoryStreamPolicyForItem}from"../history/history-stream-policy.js";import{canonicalDocument,parseItemDocument,serializeItemDocument}from"../item/item-format.js";import{resolveItemTypeRegistry}from"../item/type-registry.js";import{effectiveItemFormatVersion,requiredItemFormatVersion}from"../item/item-format-version.js";import{assertProjectRuntimeFormatGuard}from"../../sdk/environment/project-runtime-compatibility.js";import{acquireLockLease}from"../lock/lock.js";import{isFileMissingError,writeFileAtomic}from"../fs/fs-utils.js";import{isUtf8}from"node:buffer";import{normalizeItemId,normalizeRawItemId}from"../item/id.js";import{acquireItemMetadataDerivedIndexLock,listAllDocumentCandidatesCached,listAllDocumentsCached,listAllDocumentsCachedLight,refreshItemMetadataDerivedIndex}from"./item-metadata-cache.js";import{getHistoryPath,getItemPath,ITEM_FILE_EXTENSIONS,resolveWorkspaceRoot}from"./paths.js";import{resolveGovernanceKnobs}from"./settings.js";import{assertReadableTrackerRoot}from"./tracker-preflight.js";import{resolveClaimPrincipal}from"../shared/author.js";import{nowIso}from"../shared/time.js";async function fileExists(targetPath){try{return await fs.access(targetPath),!0}catch{return!1}}function isErrno(error,code){return typeof error=="object"&&error!==null&&"code"in error&&error.code===code}function appendWarning(warnings,warning){warnings&&(warnings.includes(warning)||warnings.push(warning))}function resolveActiveExtensionFieldNames(explicit){return explicit??collectRegisteredItemFieldNames(getActiveExtensionRegistrations())}function resolveItemFormatSearchOrder(preferredFormat){return preferredFormat==="toon"?["toon","json_markdown"]:preferredFormat==="json_markdown"?["json_markdown","toon"]:["toon","json_markdown"]}async function locateItem(pmRoot,rawId,idPrefix="pm-",preferredFormat,typeToFolder=TYPE_TO_FOLDER){const trimmedRawId=rawId.trim(),exactRawId=trimmedRawId.startsWith("#")?trimmedRawId.slice(1):trimmedRawId;if(exactRawId.length===0)return null;const normalizedId=normalizeItemId(rawId,idPrefix),rawNormalizedId=normalizeRawItemId(rawId),candidateIds=[...new Set([exactRawId,normalizedId,rawNormalizedId])].filter(candidateId=>candidateId.length>0),entries=Object.entries(typeToFolder),searchOrder=resolveItemFormatSearchOrder(preferredFormat);for(const candidateId of candidateIds){const matches=new Map;for(const[type]of entries)for(const itemFormat of searchOrder){const itemPath=getItemPath(pmRoot,type,candidateId,itemFormat,typeToFolder);await fileExists(itemPath)&&matches.set(itemPath,matches.get(itemPath)??{id:candidateId,type,itemPath,item_format:itemFormat})}if(matches.size>1){const paths=[...matches.keys()].map(itemPath=>path.relative(pmRoot,itemPath).split(path.sep).join("/")).sort();throw new PmCliError(`Item ${candidateId} has ambiguous identity across ${paths.join(", ")}. Preserve both documents and inspect pm ops validate --check-storage-integrity before resolving the collision.`,EXIT_CODE.CONFLICT,{code:"item_identity_ambiguous",item_id:candidateId,paths})}for(const match of matches.values())return match}return null}async function readLocatedItem(item,options={}){const snapshot=await readLocatedItemSnapshot(item,options);if(snapshot.error!==null)throw snapshot.error;return{raw:snapshot.raw,document:snapshot.document}}async function readLocatedItemSnapshot(item,options={}){const bytes=await fs.readFile(item.itemPath);if(!isUtf8(bytes))throw new PmCliError("Item contains invalid UTF-8; preserve a binary backup before recovering it.",EXIT_CODE.CONFLICT,{code:"item_document_encoding_invalid",item_id:item.id,item_path:item.itemPath,byte_length:bytes.length,empty:!1});const raw=bytes.toString("utf8");await runActiveOnReadHooks({path:item.itemPath,scope:"project"});let document;try{document=parseItemDocument(raw,{format:item.item_format,requireSupportedFormat:!0,schema:options.schema,extensionFieldNames:resolveActiveExtensionFieldNames(options.extensionFieldNames),onWarning:warning=>appendWarning(options.warnings,warning)})}catch(error){if(error instanceof PmCliError&&error.code==="item_format_version_unsupported")throw new PmCliError(`Item ${item.id}: ${error.message}`,error.exitCode,{...error.context,item_id:item.id,item_path:item.itemPath});if(error instanceof PmCliError&&error.code==="item_document_invalid")return{raw,document:null,error:new PmCliError(`Cannot read ${item.id} at ${item.itemPath}${bytes.length===0?" (zero-length file)":""}: ${error.message}`,error.exitCode,{...error.context,item_id:item.id,item_path:item.itemPath,byte_length:bytes.length,empty:bytes.length===0,nextSteps:[`Run pm history ${item.id} --full, then pm restore ${item.id} <version> to recover a recorded state.`]})};throw error}return{raw,document,error:null}}async function listAllItemMetadata(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema){await assertReadableTrackerRoot(pmRoot);const documents=await listAllDocumentsCached(pmRoot,preferredFormat,typeToFolder,warnings,schema);return recordItemMetadataEnumeration(documents.length),documents.map(document=>document.metadata)}async function listAllItemMetadataLight(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema){await assertReadableTrackerRoot(pmRoot);const documents=await listAllDocumentsCachedLight(pmRoot,preferredFormat,typeToFolder,warnings,schema);return recordItemMetadataEnumeration(documents.length),documents.map(document=>document.metadata)}async function listAllItemMetadataWithBody(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema,options={}){await assertReadableTrackerRoot(pmRoot);const candidates=await listAllDocumentCandidatesCached(pmRoot,preferredFormat,typeToFolder,warnings,schema,{includeBody:!0,forceSourceScan:options.forceSourceScan});return recordItemMetadataEnumeration(candidates.length),candidates.map(candidate=>({...candidate.metadata,body:candidate.body}))}function createMutationGuardSdk(params){return{async get(id){const located=await locateItem(params.pmRoot,id,params.settings.id_prefix,params.settings.item_format,params.typeToFolder);if(!located)return null;const{document}=await readLocatedItem(located,{schema:params.settings.schema});return{item:document.metadata,body:document.body}},list:()=>listAllItemMetadata(params.pmRoot,params.settings.item_format,params.typeToFolder,void 0,params.settings.schema)}}async function listKnownItemIds(pmRoot,typeToFolder){const folders=new Set(Object.values(typeToFolder)),allIds=[];return await Promise.all([...folders].map(async folder=>{try{const entries=await fs.readdir(path.join(pmRoot,folder));for(const entry of entries)for(const ext of ITEM_FILE_EXTENSIONS)if(entry.toLowerCase().endsWith(ext)){allIds.push(entry.slice(0,-ext.length));break}}catch{}})),allIds}async function buildDidYouMeanSuggestions(pmRoot,badId,idPrefix,typeToFolder){const normalized=normalizeItemId(badId,idPrefix),ids=await listKnownItemIds(pmRoot,typeToFolder);if(ids.length===0)return[];const limit=Math.max(3,Math.floor(normalized.length/2));return ids.map(id=>({id,distance:levenshteinDistanceWithinLimit(id,normalized,limit)})).filter(entry=>entry.distance!==null).sort((left,right)=>left.distance-right.distance).slice(0,3).map(entry=>entry.id)}async function buildItemNotFoundError(pmRoot,badId,idPrefix,typeToFolder){const deleted=await buildDeletedItemError(pmRoot,badId,idPrefix);if(deleted)return deleted;const suggestions=await buildDidYouMeanSuggestions(pmRoot,badId,idPrefix,typeToFolder),nextSteps=["Confirm the active --path/PM_PATH scope, then retry with a valid id."];return suggestions.length>0&&nextSteps.unshift(`Did you mean one of: ${suggestions.join(", ")}?`),new PmCliError(`Item ${badId} not found`,EXIT_CODE.NOT_FOUND,{nextSteps})}function bypassesAssigneeConflict(op,bypassAssigneeConflict){return op==="claim"||bypassAssigneeConflict===!0&&(op==="comment_add"||op==="comment_edit"||op==="comment_delete"||op==="note_add"||op==="learning_add"||op==="release"||op==="update"||op==="update_ownership_bypass"||op==="update_audit")}async function prepareLockedItem(params){const typeToFolder=params.typeToFolder??resolveItemTypeRegistry(params.settings,getActiveExtensionRegistrations()).type_to_folder,located=await locateItem(params.pmRoot,params.id,params.settings.id_prefix,params.settings.item_format,typeToFolder);if(!located)throw await buildItemNotFoundError(params.pmRoot,params.id,params.settings.id_prefix,typeToFolder);const lease=await acquireLockLease(params.pmRoot,located.id,params.settings.locks.ttl_seconds,params.author,!!params.force,params.settings.governance.force_required_for_stale_lock,params.settings.locks.wait_ms,{waitPolicy:"progress"}),releaseLock=lease.release;try{const warnings=[],{raw:originalRaw,document}=await readLocatedItem(located,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames,warnings}),assigned=document.metadata.assignee?.trim(),assignedPrincipal=document.metadata.claim_principal?.trim()||assigned,callerPrincipal=resolveClaimPrincipal(params.author),governance=resolveGovernanceKnobs(params.settings);if(assigned&&assignedPrincipal!==callerPrincipal&&!params.force&&!bypassesAssigneeConflict(params.op,params.bypassAssigneeConflict)){if(governance.ownership_enforcement==="strict")throw new PmCliError(`Item ${located.id} is assigned to ${assigned}. Use --force to override.`,EXIT_CODE.CONFLICT);governance.ownership_enforcement==="warn"&&warnings.push(`ownership_warning:assignee_conflict:${located.id}:${assigned}`)}return{typeToFolder,located,originalRaw,document,warnings,releaseLock,lease}}catch(error){throw await releaseLock(),error}}async function commitLockedItemWrite(lease,located,originalRaw,commit){return lease.fence(async()=>{let currentRaw;try{currentRaw=await fs.readFile(located.itemPath,"utf8")}catch(error){if(!isFileMissingError(error))throw error;currentRaw=null}if(currentRaw!==originalRaw)throw new PmCliError(`Item ${located.id} changed after this mutation read it; refusing to overwrite the newer revision. Nothing was written.`,EXIT_CODE.CONFLICT,{code:"stale_revision",item_id:located.id,reason:currentRaw===null?"item_removed":"item_revision_changed",required:"Re-read the item and apply the mutation again; the newer stored revision was kept."});return commit()})}function resolveItemStoreWriteOverride(serviceWriteOverride,targetItemPath,serializedAfter){if(!serviceWriteOverride.handled||typeof serviceWriteOverride.result!="object"||serviceWriteOverride.result===null)return{effectiveTargetItemPath:targetItemPath,effectiveSerializedAfter:serializedAfter,skipItemWrite:!1};const overrideRecord=serviceWriteOverride.result;return{effectiveTargetItemPath:typeof overrideRecord.target_item_path=="string"&&overrideRecord.target_item_path.trim().length>0?overrideRecord.target_item_path:targetItemPath,effectiveSerializedAfter:typeof overrideRecord.contents=="string"?overrideRecord.contents:serializedAfter,skipItemWrite:overrideRecord.skip_write===!0}}async function resolveItemStoreDeleteOverride(payload){const override=await runActiveServiceOverride("item_store_delete",payload),record=override.handled&&typeof override.result=="object"&&override.result!==null?override.result:{};return{effectiveItemPath:typeof record.item_path=="string"&&record.item_path.trim().length>0?record.item_path:payload.item_path,skipDelete:record.skip_delete===!0,warnings:override.warnings}}async function rollbackMutatedItemWrite(params){if(!params.skipItemWrite){if(params.effectiveTargetItemPath!==params.originalItemPath){await writeFileAtomic(params.originalItemPath,params.originalRaw),await fs.rm(params.effectiveTargetItemPath,{force:!0});return}await writeFileAtomic(params.originalItemPath,params.originalRaw)}}async function mutateItemWithDeferredHistoryContext(params){normalizeHistoryOperationForWrite(params.op);const prepared=await prepareLockedItem({pmRoot:params.pmRoot,settings:params.settings,id:params.id,op:params.op,author:params.author,force:params.force,bypassAssigneeConflict:params.bypassAssigneeConflict,extensionFieldNames:params.extensionFieldNames,typeToFolder:params.typeToFolder}),{typeToFolder,located,originalRaw,document,warnings:parseWarnings,releaseLock,lease}=prepared;try{assertItemMutationPreconditions(params.pmRoot,document);const beforeDocument=canonicalDocument(document,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),mutableDocument=canonicalDocument(structuredClone(document),{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),mutation=await params.mutate(mutableDocument);if(params.skipNoop===!0&&mutation.changedFields.length===0)return{item:beforeDocument.metadata,body:beforeDocument.body,changedFields:[],warnings:[...parseWarnings,...mutation.warnings??[]]};const historyContext={...params.resolveHistoryContext?.(),...checkpointMutationHistoryContext(params.pmRoot,located.id),...itemMutationPreconditionHistoryContext(params.pmRoot,document)},requiredFormat=Math.max(requiredItemFormatVersion(beforeDocument.metadata),requiredItemFormatVersion(mutableDocument.metadata));assertProjectRuntimeFormatGuard(resolveWorkspaceRoot(params.pmRoot),requiredFormat),requiredFormat>effectiveItemFormatVersion(mutableDocument.metadata)&&(mutableDocument.metadata.pm_format_version=requiredFormat,mutation.changedFields.push("pm_format_version")),mutableDocument.metadata.updated_at=nowIso();const afterDocument=canonicalDocument(mutableDocument,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),workflowPolicy=await enforceWorkflowMutation({pmRoot:params.pmRoot,settings:params.settings,operation:params.op,author:params.author,before:beforeDocument,after:afterDocument});await runActiveBeforeMutationHooks({pm_root:params.pmRoot,operation:params.op,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields,sdk:createMutationGuardSdk({pmRoot:params.pmRoot,settings:params.settings,typeToFolder})});const historyPolicy=await enforceHistoryStreamPolicyForItem({pmRoot:params.pmRoot,settings:params.settings,itemId:located.id,commandLabel:params.op}),targetItemFormat="toon",serializedAfter=serializeItemDocument(afterDocument,{format:targetItemFormat,schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),targetItemPath=getItemPath(params.pmRoot,afterDocument.metadata.type,located.id,targetItemFormat,typeToFolder),historyPath=getHistoryPath(params.pmRoot,located.id),committed=await commitLockedItemWrite(lease,located,originalRaw,async()=>{const serviceWriteOverride=await runActiveServiceOverride("item_store_write",{op:params.op,pm_root:params.pmRoot,item_id:located.id,source_item_path:located.itemPath,target_item_path:targetItemPath,history_path:historyPath,item_format:targetItemFormat,before:beforeDocument,after:afterDocument,contents:serializedAfter}),{effectiveTargetItemPath:effectiveTargetItemPath2,effectiveSerializedAfter,skipItemWrite}=resolveItemStoreWriteOverride(serviceWriteOverride,targetItemPath,serializedAfter),releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);let derivedIndexWarnings2=[];try{skipItemWrite||await writeFileAtomic(effectiveTargetItemPath2,effectiveSerializedAfter),!skipItemWrite&&effectiveTargetItemPath2!==located.itemPath&&await fs.rm(located.itemPath);const entry=createHistoryEntry({nowIso:afterDocument.metadata.updated_at,author:params.author,op:params.op,before:beforeDocument,after:afterDocument,message:params.message,context:workflowPolicy.decisions.length===0?Object.keys(historyContext).length===0?void 0:historyContext:{...historyContext,workflow_policies:workflowPolicy.decisions}});try{await appendHistoryEntry(historyPath,entry)}catch(error){throw await rollbackMutatedItemWrite({skipItemWrite,effectiveTargetItemPath:effectiveTargetItemPath2,originalItemPath:located.itemPath,originalRaw}),error}skipItemWrite||(derivedIndexWarnings2=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder,schema:params.settings.schema,itemPath:effectiveTargetItemPath2,previousItemPath:located.itemPath,document:afterDocument}))}finally{await releaseDerivedIndexLock()}return{derivedIndexWarnings:derivedIndexWarnings2,effectiveTargetItemPath:effectiveTargetItemPath2,overrideWarnings:serviceWriteOverride.warnings}}),{derivedIndexWarnings,effectiveTargetItemPath}=committed;advanceItemMutationPreconditions(params.pmRoot,afterDocument);const hookWarnings=[...await runActiveOnWriteHooks({path:effectiveTargetItemPath,scope:"project",op:params.op,item_id:afterDocument.metadata.id,item_type:afterDocument.metadata.type,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields}),...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:`${params.op}:history`,item_id:afterDocument.metadata.id,item_type:afterDocument.metadata.type,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields})];return recordAfterCommandAffectedItem({id:afterDocument.metadata.id,op:params.op,item_type:afterDocument.metadata.type,previous_status:beforeDocument.metadata.status,status:afterDocument.metadata.status,previous:projectAfterCommandItemSnapshot(beforeDocument.metadata,mutation.changedFields),current:projectAfterCommandItemSnapshot(afterDocument.metadata,mutation.changedFields),changed_fields:mutation.changedFields}),{item:afterDocument.metadata,body:afterDocument.body,changedFields:mutation.changedFields,warnings:[...parseWarnings,...mutation.warnings??[],...workflowPolicy.warnings,...historyPolicy.warnings,...committed.overrideWarnings,...derivedIndexWarnings,...hookWarnings]}}finally{await releaseLock()}}async function mutateItemWithHistoryContext(params){const{historyContext,...mutationParams}=params;return mutateItemWithDeferredHistoryContext({...mutationParams,resolveHistoryContext:()=>historyContext})}async function mutateItemWithHistoryContextResolver(params){return mutateItemWithDeferredHistoryContext(params)}async function mutateItem(params){return mutateItemWithDeferredHistoryContext(params)}const itemStoreTestOnly={appendWarning,bypassesAssigneeConflict,buildDidYouMeanSuggestions,isErrno};async function deleteItem(params){const prepared=await prepareLockedItem({pmRoot:params.pmRoot,settings:params.settings,id:params.id,op:"delete",author:params.author,force:params.force}),{located,originalRaw,document,warnings:parseWarnings,releaseLock,lease}=prepared;try{const extensionFieldNames=resolveActiveExtensionFieldNames(void 0),beforeDocument=canonicalDocument(document,{schema:params.settings.schema,extensionFieldNames}),workflowPolicy=await enforceWorkflowMutation({pmRoot:params.pmRoot,settings:params.settings,operation:"delete",author:params.author,before:beforeDocument,after:null,dryRun:params.dryRun});await runActiveBeforeMutationHooks({pm_root:params.pmRoot,operation:"delete",before:beforeDocument,after:null,changed_fields:["deleted"],sdk:createMutationGuardSdk({pmRoot:params.pmRoot,settings:params.settings,typeToFolder:prepared.typeToFolder})});const historyPolicy=await enforceHistoryStreamPolicyForItem({pmRoot:params.pmRoot,settings:params.settings,itemId:located.id,commandLabel:"delete"}),deletionTimestamp=nowIso(),tombstoneDocument=EMPTY_CANONICAL_DOCUMENT,historyEntry=createHistoryEntry({nowIso:deletionTimestamp,author:params.author,op:"delete",before:beforeDocument,after:tombstoneDocument,message:params.message,context:workflowPolicy.decisions.length===0?void 0:{workflow_policies:workflowPolicy.decisions}}),historyPath=getHistoryPath(params.pmRoot,located.id),runDeleteOverride=()=>resolveItemStoreDeleteOverride({op:"delete",pm_root:params.pmRoot,item_id:located.id,item_path:located.itemPath,history_path:historyPath,before:beforeDocument});if(params.dryRun===!0){const preview=await runDeleteOverride();return{item:beforeDocument.metadata,changedFields:["deleted"],targetPath:preview.effectiveItemPath,warnings:[...parseWarnings,...workflowPolicy.warnings,...historyPolicy.warnings,...preview.warnings]}}const committed=await commitLockedItemWrite(lease,located,originalRaw,async()=>{const{effectiveItemPath:effectiveItemPath2,skipDelete,warnings}=await runDeleteOverride(),releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);let derivedIndexWarnings2=[];try{skipDelete||await fs.rm(effectiveItemPath2);try{await appendHistoryEntry(historyPath,historyEntry)}catch(error){throw skipDelete||await writeFileAtomic(effectiveItemPath2,originalRaw),error}skipDelete||(derivedIndexWarnings2=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder:prepared.typeToFolder,schema:params.settings.schema,itemPath:effectiveItemPath2,document:null}))}finally{await releaseDerivedIndexLock()}return{derivedIndexWarnings:derivedIndexWarnings2,effectiveItemPath:effectiveItemPath2,overrideWarnings:warnings}}),{derivedIndexWarnings,effectiveItemPath}=committed,hookWarnings=[...await runActiveOnWriteHooks({path:effectiveItemPath,scope:"project",op:"delete",item_id:beforeDocument.metadata.id,item_type:beforeDocument.metadata.type,before:beforeDocument,after:tombstoneDocument,changed_fields:["deleted"]}),...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:"delete:history",item_id:beforeDocument.metadata.id,item_type:beforeDocument.metadata.type,before:beforeDocument,after:tombstoneDocument,changed_fields:["deleted"]})];return recordAfterCommandAffectedItem({id:beforeDocument.metadata.id,op:"delete",item_type:beforeDocument.metadata.type,previous_status:beforeDocument.metadata.status,previous:projectAfterCommandItemSnapshot(beforeDocument.metadata,Object.keys(beforeDocument.metadata)),changed_fields:["deleted"]}),{item:beforeDocument.metadata,changedFields:["deleted"],warnings:[...parseWarnings,...workflowPolicy.warnings,...historyPolicy.warnings,...committed.overrideWarnings,...derivedIndexWarnings,...hookWarnings]}}finally{await releaseLock()}}export{buildItemNotFoundError,createMutationGuardSdk,deleteItem,itemStoreTestOnly,listAllItemMetadata,listAllItemMetadataLight,listAllItemMetadataWithBody,locateItem,mutateItem,mutateItemWithHistoryContext,mutateItemWithHistoryContextResolver,readLocatedItem,readLocatedItemSnapshot};
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]="daea02fe-fa67-5891-b31a-517a07faec58")}catch{}})();import fs from"node:fs/promises";import{buildDeletedItemError}from"../history/tombstone.js";import{normalizeHistoryOperationForWrite}from"../history/operation-contract.js";import{enforceWorkflowMutation}from"../policy/workflow-policy-store.js";import{recordItemMetadataEnumeration}from"./item-metadata-read-work.js";import{advanceItemMutationPreconditions,assertItemMutationPreconditions,itemMutationPreconditionHistoryContext}from"./item-mutation-precondition.js";import{checkpointMutationHistoryContext}from"../checkpoint/mutation-context.js";import path from"node:path";import{getActiveExtensionRegistrations,projectAfterCommandItemSnapshot,recordAfterCommandAffectedItem,runActiveOnReadHooks,runActiveBeforeMutationHooks,runActiveOnWriteHooks,runActiveServiceOverride}from"../extensions/index.js";import{collectRegisteredItemFieldNames}from"../extensions/item-fields.js";import{EMPTY_CANONICAL_DOCUMENT,EXIT_CODE,TYPE_TO_FOLDER}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{levenshteinDistanceWithinLimit}from"../shared/levenshtein.js";import{appendHistoryEntry,createHistoryEntry}from"../history/history.js";import{enforceHistoryStreamPolicyForItem}from"../history/history-stream-policy.js";import{canonicalDocument,parseItemDocument,serializeItemDocument}from"../item/item-format.js";import{resolveItemTypeRegistry}from"../item/type-registry.js";import{effectiveItemFormatVersion,requiredItemFormatVersion}from"../item/item-format-version.js";import{assertProjectRuntimeFormatGuard}from"../../sdk/environment/project-runtime-compatibility.js";import{acquireLockLease}from"../lock/lock.js";import{isFileMissingError,writeFileAtomic}from"../fs/fs-utils.js";import{isUtf8}from"node:buffer";import{normalizeItemId,normalizeRawItemId}from"../item/id.js";import{acquireItemMetadataDerivedIndexLock,listAllDocumentCandidatesCached,listAllDocumentsCached,listAllDocumentsCachedLight,refreshItemMetadataDerivedIndex}from"./item-metadata-cache.js";import{getHistoryPath,getItemPath,ITEM_FILE_EXTENSIONS,resolveWorkspaceRoot}from"./paths.js";import{resolveGovernanceKnobs}from"./settings.js";import{assertReadableTrackerRoot}from"./tracker-preflight.js";import{resolveClaimPrincipal}from"../shared/author.js";import{nowIso}from"../shared/time.js";async function fileExists(targetPath){try{return await fs.access(targetPath),!0}catch{return!1}}function isErrno(error,code){return typeof error=="object"&&error!==null&&"code"in error&&error.code===code}function appendWarning(warnings,warning){warnings&&(warnings.includes(warning)||warnings.push(warning))}function resolveActiveExtensionFieldNames(explicit){return explicit??collectRegisteredItemFieldNames(getActiveExtensionRegistrations())}function resolveItemFormatSearchOrder(preferredFormat){return preferredFormat==="toon"?["toon","json_markdown"]:preferredFormat==="json_markdown"?["json_markdown","toon"]:["toon","json_markdown"]}async function locateItem(pmRoot,rawId,idPrefix="pm-",preferredFormat,typeToFolder=TYPE_TO_FOLDER){const trimmedRawId=rawId.trim(),exactRawId=trimmedRawId.startsWith("#")?trimmedRawId.slice(1):trimmedRawId;if(exactRawId.length===0)return null;const normalizedId=normalizeItemId(rawId,idPrefix),rawNormalizedId=normalizeRawItemId(rawId),candidateIds=[...new Set([exactRawId,normalizedId,rawNormalizedId])].filter(candidateId=>candidateId.length>0),entries=Object.entries(typeToFolder),searchOrder=resolveItemFormatSearchOrder(preferredFormat);for(const candidateId of candidateIds){const matches=new Map;for(const[type]of entries)for(const itemFormat of searchOrder){const itemPath=getItemPath(pmRoot,type,candidateId,itemFormat,typeToFolder);await fileExists(itemPath)&&matches.set(itemPath,matches.get(itemPath)??{id:candidateId,type,itemPath,item_format:itemFormat})}if(matches.size>1){const paths=[...matches.keys()].map(itemPath=>path.relative(pmRoot,itemPath).split(path.sep).join("/")).sort();throw new PmCliError(`Item ${candidateId} has ambiguous identity across ${paths.join(", ")}. Preserve both documents and inspect pm ops validate --check-storage-integrity before resolving the collision.`,EXIT_CODE.CONFLICT,{code:"item_identity_ambiguous",item_id:candidateId,paths})}for(const match of matches.values())return match}return null}async function readLocatedItem(item,options={}){const snapshot=await readLocatedItemSnapshot(item,options);if(snapshot.error!==null)throw snapshot.error;return{raw:snapshot.raw,document:snapshot.document}}async function readLocatedItemSnapshot(item,options={}){const bytes=await fs.readFile(item.itemPath);if(!isUtf8(bytes))throw new PmCliError("Item contains invalid UTF-8; preserve a binary backup before recovering it.",EXIT_CODE.CONFLICT,{code:"item_document_encoding_invalid",item_id:item.id,item_path:item.itemPath,byte_length:bytes.length,empty:!1});const raw=bytes.toString("utf8");await runActiveOnReadHooks({path:item.itemPath,scope:"project"});let document;try{document=parseItemDocument(raw,{format:item.item_format,requireSupportedFormat:!0,schema:options.schema,extensionFieldNames:resolveActiveExtensionFieldNames(options.extensionFieldNames),onWarning:warning=>appendWarning(options.warnings,warning)})}catch(error){if(error instanceof PmCliError&&error.code==="item_format_version_unsupported")throw new PmCliError(`Item ${item.id}: ${error.message}`,error.exitCode,{...error.context,item_id:item.id,item_path:item.itemPath});if(error instanceof PmCliError&&error.code==="item_document_invalid")return{raw,document:null,error:new PmCliError(`Cannot read ${item.id} at ${item.itemPath}${bytes.length===0?" (zero-length file)":""}: ${error.message}`,error.exitCode,{...error.context,item_id:item.id,item_path:item.itemPath,byte_length:bytes.length,empty:bytes.length===0,nextSteps:[`Run pm history ${item.id} --full, then pm restore ${item.id} <version> to recover a recorded state.`]})};throw error}return{raw,document,error:null}}async function listAllItemMetadata(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema){await assertReadableTrackerRoot(pmRoot);const documents=await listAllDocumentsCached(pmRoot,preferredFormat,typeToFolder,warnings,schema);return recordItemMetadataEnumeration(documents.length),documents.map(document=>document.metadata)}async function listAllItemMetadataLight(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema){await assertReadableTrackerRoot(pmRoot);const documents=await listAllDocumentsCachedLight(pmRoot,preferredFormat,typeToFolder,warnings,schema);return recordItemMetadataEnumeration(documents.length),documents.map(document=>document.metadata)}async function listAllItemMetadataWithBody(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema,options={}){await assertReadableTrackerRoot(pmRoot);const candidates=await listAllDocumentCandidatesCached(pmRoot,preferredFormat,typeToFolder,warnings,schema,{includeBody:!0,forceSourceScan:options.forceSourceScan});return recordItemMetadataEnumeration(candidates.length),candidates.map(candidate=>({...candidate.metadata,body:candidate.body}))}function createMutationGuardSdk(params){return{async get(id){const located=await locateItem(params.pmRoot,id,params.settings.id_prefix,params.settings.item_format,params.typeToFolder);if(!located)return null;const{document}=await readLocatedItem(located,{schema:params.settings.schema});return{item:document.metadata,body:document.body}},list:()=>listAllItemMetadata(params.pmRoot,params.settings.item_format,params.typeToFolder,void 0,params.settings.schema)}}async function listKnownItemIds(pmRoot,typeToFolder){const folders=new Set(Object.values(typeToFolder)),allIds=[];return await Promise.all([...folders].map(async folder=>{try{const entries=await fs.readdir(path.join(pmRoot,folder));for(const entry of entries)for(const ext of ITEM_FILE_EXTENSIONS)if(entry.toLowerCase().endsWith(ext)){allIds.push(entry.slice(0,-ext.length));break}}catch{}})),allIds}async function buildDidYouMeanSuggestions(pmRoot,badId,idPrefix,typeToFolder){const normalized=normalizeItemId(badId,idPrefix),ids=await listKnownItemIds(pmRoot,typeToFolder);if(ids.length===0)return[];const limit=Math.max(3,Math.floor(normalized.length/2));return ids.map(id=>({id,distance:levenshteinDistanceWithinLimit(id,normalized,limit)})).filter(entry=>entry.distance!==null).sort((left,right)=>left.distance-right.distance).slice(0,3).map(entry=>entry.id)}async function buildItemNotFoundError(pmRoot,badId,idPrefix,typeToFolder){const deleted=await buildDeletedItemError(pmRoot,badId,idPrefix);if(deleted)return deleted;const suggestions=await buildDidYouMeanSuggestions(pmRoot,badId,idPrefix,typeToFolder),nextSteps=["Confirm the active --path/PM_PATH scope, then retry with a valid id."];return suggestions.length>0&&nextSteps.unshift(`Did you mean one of: ${suggestions.join(", ")}?`),new PmCliError(`Item ${badId} not found`,EXIT_CODE.NOT_FOUND,{code:"item_not_found",id:badId,nextSteps})}function bypassesAssigneeConflict(op,bypassAssigneeConflict){return op==="claim"||bypassAssigneeConflict===!0&&(op==="comment_add"||op==="comment_edit"||op==="comment_delete"||op==="note_add"||op==="learning_add"||op==="release"||op==="update"||op==="update_ownership_bypass"||op==="update_audit")}async function prepareLockedItem(params){const typeToFolder=params.typeToFolder??resolveItemTypeRegistry(params.settings,getActiveExtensionRegistrations()).type_to_folder,located=await locateItem(params.pmRoot,params.id,params.settings.id_prefix,params.settings.item_format,typeToFolder);if(!located)throw await buildItemNotFoundError(params.pmRoot,params.id,params.settings.id_prefix,typeToFolder);const lease=await acquireLockLease(params.pmRoot,located.id,params.settings.locks.ttl_seconds,params.author,!!params.force,params.settings.governance.force_required_for_stale_lock,params.settings.locks.wait_ms,{waitPolicy:"progress"}),releaseLock=lease.release;try{const warnings=[],{raw:originalRaw,document}=await readLocatedItem(located,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames,warnings}),assigned=document.metadata.assignee?.trim(),assignedPrincipal=document.metadata.claim_principal?.trim()||assigned,callerPrincipal=resolveClaimPrincipal(params.author),governance=resolveGovernanceKnobs(params.settings);if(assigned&&assignedPrincipal!==callerPrincipal&&!params.force&&!bypassesAssigneeConflict(params.op,params.bypassAssigneeConflict)){if(governance.ownership_enforcement==="strict")throw new PmCliError(`Item ${located.id} is assigned to ${assigned}. Use --force to override.`,EXIT_CODE.CONFLICT);governance.ownership_enforcement==="warn"&&warnings.push(`ownership_warning:assignee_conflict:${located.id}:${assigned}`)}return{typeToFolder,located,originalRaw,document,warnings,releaseLock,lease}}catch(error){throw await releaseLock(),error}}async function commitLockedItemWrite(lease,located,originalRaw,commit){return lease.fence(async()=>{let currentRaw;try{currentRaw=await fs.readFile(located.itemPath,"utf8")}catch(error){if(!isFileMissingError(error))throw error;currentRaw=null}if(currentRaw!==originalRaw)throw new PmCliError(`Item ${located.id} changed after this mutation read it; refusing to overwrite the newer revision. Nothing was written.`,EXIT_CODE.CONFLICT,{code:"stale_revision",item_id:located.id,reason:currentRaw===null?"item_removed":"item_revision_changed",required:"Re-read the item and apply the mutation again; the newer stored revision was kept."});return commit()})}function resolveItemStoreWriteOverride(serviceWriteOverride,targetItemPath,serializedAfter){if(!serviceWriteOverride.handled||typeof serviceWriteOverride.result!="object"||serviceWriteOverride.result===null)return{effectiveTargetItemPath:targetItemPath,effectiveSerializedAfter:serializedAfter,skipItemWrite:!1};const overrideRecord=serviceWriteOverride.result;return{effectiveTargetItemPath:typeof overrideRecord.target_item_path=="string"&&overrideRecord.target_item_path.trim().length>0?overrideRecord.target_item_path:targetItemPath,effectiveSerializedAfter:typeof overrideRecord.contents=="string"?overrideRecord.contents:serializedAfter,skipItemWrite:overrideRecord.skip_write===!0}}async function resolveItemStoreDeleteOverride(payload){const override=await runActiveServiceOverride("item_store_delete",payload),record=override.handled&&typeof override.result=="object"&&override.result!==null?override.result:{};return{effectiveItemPath:typeof record.item_path=="string"&&record.item_path.trim().length>0?record.item_path:payload.item_path,skipDelete:record.skip_delete===!0,warnings:override.warnings}}async function rollbackMutatedItemWrite(params){if(!params.skipItemWrite){if(params.effectiveTargetItemPath!==params.originalItemPath){await writeFileAtomic(params.originalItemPath,params.originalRaw),await fs.rm(params.effectiveTargetItemPath,{force:!0});return}await writeFileAtomic(params.originalItemPath,params.originalRaw)}}async function mutateItemWithDeferredHistoryContext(params){normalizeHistoryOperationForWrite(params.op);const prepared=await prepareLockedItem({pmRoot:params.pmRoot,settings:params.settings,id:params.id,op:params.op,author:params.author,force:params.force,bypassAssigneeConflict:params.bypassAssigneeConflict,extensionFieldNames:params.extensionFieldNames,typeToFolder:params.typeToFolder}),{typeToFolder,located,originalRaw,document,warnings:parseWarnings,releaseLock,lease}=prepared;try{assertItemMutationPreconditions(params.pmRoot,document);const beforeDocument=canonicalDocument(document,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),mutableDocument=canonicalDocument(structuredClone(document),{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),mutation=await params.mutate(mutableDocument);if(params.skipNoop===!0&&mutation.changedFields.length===0)return{item:beforeDocument.metadata,body:beforeDocument.body,changedFields:[],warnings:[...parseWarnings,...mutation.warnings??[]]};const historyContext={...params.resolveHistoryContext?.(),...checkpointMutationHistoryContext(params.pmRoot,located.id),...itemMutationPreconditionHistoryContext(params.pmRoot,document)},requiredFormat=Math.max(requiredItemFormatVersion(beforeDocument.metadata),requiredItemFormatVersion(mutableDocument.metadata));assertProjectRuntimeFormatGuard(resolveWorkspaceRoot(params.pmRoot),requiredFormat),requiredFormat>effectiveItemFormatVersion(mutableDocument.metadata)&&(mutableDocument.metadata.pm_format_version=requiredFormat,mutation.changedFields.push("pm_format_version")),mutableDocument.metadata.updated_at=nowIso();const afterDocument=canonicalDocument(mutableDocument,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),workflowPolicy=await enforceWorkflowMutation({pmRoot:params.pmRoot,settings:params.settings,operation:params.op,author:params.author,before:beforeDocument,after:afterDocument});await runActiveBeforeMutationHooks({pm_root:params.pmRoot,operation:params.op,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields,sdk:createMutationGuardSdk({pmRoot:params.pmRoot,settings:params.settings,typeToFolder})});const historyPolicy=await enforceHistoryStreamPolicyForItem({pmRoot:params.pmRoot,settings:params.settings,itemId:located.id,commandLabel:params.op}),targetItemFormat="toon",serializedAfter=serializeItemDocument(afterDocument,{format:targetItemFormat,schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),targetItemPath=getItemPath(params.pmRoot,afterDocument.metadata.type,located.id,targetItemFormat,typeToFolder),historyPath=getHistoryPath(params.pmRoot,located.id),committed=await commitLockedItemWrite(lease,located,originalRaw,async()=>{const serviceWriteOverride=await runActiveServiceOverride("item_store_write",{op:params.op,pm_root:params.pmRoot,item_id:located.id,source_item_path:located.itemPath,target_item_path:targetItemPath,history_path:historyPath,item_format:targetItemFormat,before:beforeDocument,after:afterDocument,contents:serializedAfter}),{effectiveTargetItemPath:effectiveTargetItemPath2,effectiveSerializedAfter,skipItemWrite}=resolveItemStoreWriteOverride(serviceWriteOverride,targetItemPath,serializedAfter),releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);let derivedIndexWarnings2=[];try{skipItemWrite||await writeFileAtomic(effectiveTargetItemPath2,effectiveSerializedAfter),!skipItemWrite&&effectiveTargetItemPath2!==located.itemPath&&await fs.rm(located.itemPath);const entry=createHistoryEntry({nowIso:afterDocument.metadata.updated_at,author:params.author,op:params.op,before:beforeDocument,after:afterDocument,message:params.message,context:workflowPolicy.decisions.length===0?Object.keys(historyContext).length===0?void 0:historyContext:{...historyContext,workflow_policies:workflowPolicy.decisions}});try{await appendHistoryEntry(historyPath,entry)}catch(error){throw await rollbackMutatedItemWrite({skipItemWrite,effectiveTargetItemPath:effectiveTargetItemPath2,originalItemPath:located.itemPath,originalRaw}),error}skipItemWrite||(derivedIndexWarnings2=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder,schema:params.settings.schema,itemPath:effectiveTargetItemPath2,previousItemPath:located.itemPath,document:afterDocument}))}finally{await releaseDerivedIndexLock()}return{derivedIndexWarnings:derivedIndexWarnings2,effectiveTargetItemPath:effectiveTargetItemPath2,overrideWarnings:serviceWriteOverride.warnings}}),{derivedIndexWarnings,effectiveTargetItemPath}=committed;advanceItemMutationPreconditions(params.pmRoot,afterDocument);const hookWarnings=[...await runActiveOnWriteHooks({path:effectiveTargetItemPath,scope:"project",op:params.op,item_id:afterDocument.metadata.id,item_type:afterDocument.metadata.type,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields}),...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:`${params.op}:history`,item_id:afterDocument.metadata.id,item_type:afterDocument.metadata.type,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields})];return recordAfterCommandAffectedItem({id:afterDocument.metadata.id,op:params.op,item_type:afterDocument.metadata.type,previous_status:beforeDocument.metadata.status,status:afterDocument.metadata.status,previous:projectAfterCommandItemSnapshot(beforeDocument.metadata,mutation.changedFields),current:projectAfterCommandItemSnapshot(afterDocument.metadata,mutation.changedFields),changed_fields:mutation.changedFields}),{item:afterDocument.metadata,body:afterDocument.body,changedFields:mutation.changedFields,warnings:[...parseWarnings,...mutation.warnings??[],...workflowPolicy.warnings,...historyPolicy.warnings,...committed.overrideWarnings,...derivedIndexWarnings,...hookWarnings]}}finally{await releaseLock()}}async function mutateItemWithHistoryContext(params){const{historyContext,...mutationParams}=params;return mutateItemWithDeferredHistoryContext({...mutationParams,resolveHistoryContext:()=>historyContext})}async function mutateItemWithHistoryContextResolver(params){return mutateItemWithDeferredHistoryContext(params)}async function mutateItem(params){return mutateItemWithDeferredHistoryContext(params)}const itemStoreTestOnly={appendWarning,bypassesAssigneeConflict,buildDidYouMeanSuggestions,isErrno};async function deleteItem(params){const prepared=await prepareLockedItem({pmRoot:params.pmRoot,settings:params.settings,id:params.id,op:"delete",author:params.author,force:params.force}),{located,originalRaw,document,warnings:parseWarnings,releaseLock,lease}=prepared;try{const extensionFieldNames=resolveActiveExtensionFieldNames(void 0),beforeDocument=canonicalDocument(document,{schema:params.settings.schema,extensionFieldNames}),workflowPolicy=await enforceWorkflowMutation({pmRoot:params.pmRoot,settings:params.settings,operation:"delete",author:params.author,before:beforeDocument,after:null,dryRun:params.dryRun});await runActiveBeforeMutationHooks({pm_root:params.pmRoot,operation:"delete",before:beforeDocument,after:null,changed_fields:["deleted"],sdk:createMutationGuardSdk({pmRoot:params.pmRoot,settings:params.settings,typeToFolder:prepared.typeToFolder})});const historyPolicy=await enforceHistoryStreamPolicyForItem({pmRoot:params.pmRoot,settings:params.settings,itemId:located.id,commandLabel:"delete"}),deletionTimestamp=nowIso(),tombstoneDocument=EMPTY_CANONICAL_DOCUMENT,historyEntry=createHistoryEntry({nowIso:deletionTimestamp,author:params.author,op:"delete",before:beforeDocument,after:tombstoneDocument,message:params.message,context:workflowPolicy.decisions.length===0?void 0:{workflow_policies:workflowPolicy.decisions}}),historyPath=getHistoryPath(params.pmRoot,located.id),runDeleteOverride=()=>resolveItemStoreDeleteOverride({op:"delete",pm_root:params.pmRoot,item_id:located.id,item_path:located.itemPath,history_path:historyPath,before:beforeDocument});if(params.dryRun===!0){const preview=await runDeleteOverride();return{item:beforeDocument.metadata,changedFields:["deleted"],targetPath:preview.effectiveItemPath,warnings:[...parseWarnings,...workflowPolicy.warnings,...historyPolicy.warnings,...preview.warnings]}}const committed=await commitLockedItemWrite(lease,located,originalRaw,async()=>{const{effectiveItemPath:effectiveItemPath2,skipDelete,warnings}=await runDeleteOverride(),releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);let derivedIndexWarnings2=[];try{skipDelete||await fs.rm(effectiveItemPath2);try{await appendHistoryEntry(historyPath,historyEntry)}catch(error){throw skipDelete||await writeFileAtomic(effectiveItemPath2,originalRaw),error}skipDelete||(derivedIndexWarnings2=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder:prepared.typeToFolder,schema:params.settings.schema,itemPath:effectiveItemPath2,document:null}))}finally{await releaseDerivedIndexLock()}return{derivedIndexWarnings:derivedIndexWarnings2,effectiveItemPath:effectiveItemPath2,overrideWarnings:warnings}}),{derivedIndexWarnings,effectiveItemPath}=committed,hookWarnings=[...await runActiveOnWriteHooks({path:effectiveItemPath,scope:"project",op:"delete",item_id:beforeDocument.metadata.id,item_type:beforeDocument.metadata.type,before:beforeDocument,after:tombstoneDocument,changed_fields:["deleted"]}),...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:"delete:history",item_id:beforeDocument.metadata.id,item_type:beforeDocument.metadata.type,before:beforeDocument,after:tombstoneDocument,changed_fields:["deleted"]})];return recordAfterCommandAffectedItem({id:beforeDocument.metadata.id,op:"delete",item_type:beforeDocument.metadata.type,previous_status:beforeDocument.metadata.status,previous:projectAfterCommandItemSnapshot(beforeDocument.metadata,Object.keys(beforeDocument.metadata)),changed_fields:["deleted"]}),{item:beforeDocument.metadata,changedFields:["deleted"],warnings:[...parseWarnings,...workflowPolicy.warnings,...historyPolicy.warnings,...committed.overrideWarnings,...derivedIndexWarnings,...hookWarnings]}}finally{await releaseLock()}}export{buildItemNotFoundError,createMutationGuardSdk,deleteItem,itemStoreTestOnly,listAllItemMetadata,listAllItemMetadataLight,listAllItemMetadataWithBody,locateItem,mutateItem,mutateItemWithHistoryContext,mutateItemWithHistoryContextResolver,readLocatedItem,readLocatedItemSnapshot};
2
2
  //# sourceMappingURL=item-store.js.map
@@ -1,4 +1,9 @@
1
1
  export { resolveLinkedResourcePositionalRecovery } from "./linked-resource-recovery.js";
2
+ /** Explain unsupported lifecycle verbs using declared mutation flags, without authorizing or executing a guessed mutation. */
3
+ export declare function resolveLifecycleVerbRecovery(verb:string,availablePaths:readonly string[]):{
4
+ examples:string[][];
5
+ nextSteps:string[];
6
+ } | undefined;
2
7
  /** Derive a same-command read retry for known completeness and encoding mistakes without discarding intent. */
3
8
  export declare function resolveReadOptionRetryArgs(commandName:string,invocationArgv:readonly string[],unknownOption:string):string[] | undefined;
4
9
  /** Identify presentation intent that must not be silently dropped from an unknown-option retry. */
@@ -1,2 +1,2 @@
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]="a1730bf5-914a-5031-ae21-56bd358727e2")}catch{}})();import{renderPmCommand}from"../command-line.js";import{resolveLinkedResourcePositionalRecovery}from"./linked-resource-recovery.js";import{resolveSubcommandFlagContractsForCommand}from"../cli-contracts/flag-contracts.js";import{parseBootstrapCommandName}from"../cli-contracts/bootstrap-command-scanner.js";import{READ_OUTPUT_DIMENSION_FLAGS,READ_OUTPUT_COMPOSITION_FLAGS}from"../read-output/options.js";import{resolvePmCommandOperation}from"../cli-contracts/command-aliases.js";const READ_PROJECTION_FLAGS=new Set([...Object.values(READ_OUTPUT_DIMENSION_FLAGS),...READ_OUTPUT_COMPOSITION_FLAGS,"--full","--brief","--compact","--summary","--fields","--section","--token-budget"]),MUTATION_RECEIPT_FLAGS=new Set(["--full-changed-fields","--no-changed-fields","--id-only"]);function activitySinceCorrection(token,next){const inline=token.includes("="),value=inline?token.slice(token.indexOf("=")+1):next;if(!(!value||value.startsWith("--")))return{consumed:inline?1:2,replacement:["--from",value],conflicts:["--from"]}}function readOptionCorrection(command,flag,token,next){if(flag==="--since"&&command==="activity")return activitySinceCorrection(token,next);if(flag==="--full"&&command==="context"&&token===flag)return{consumed:1,replacement:["--depth","full"],conflicts:["--depth","--output-include","--fields","--section","--for"]};if(flag==="--depth"&&["list","search"].includes(command)){const inline=token.includes("=");return(inline?token.slice(token.indexOf("=")+1):next)!=="full"?void 0:{consumed:inline?1:2,replacement:["--full"],conflicts:["--full","--brief","--compact","--output-include","--fields","--for"]}}return flag==="--toon"&&token===flag?{consumed:1,replacement:["--output-format","toon"],conflicts:["--json","--format","--output-format","--stream"]}:void 0}function resolveReadOptionRetryArgs(commandName,invocationArgv,unknownOption){const command=commandName==="ctx"?"context":resolvePmCommandOperation(commandName);if(!["context","list","search","get","activity"].includes(command)||invocationArgv.includes("--"))return;const invoked=parseBootstrapCommandName(invocationArgv);if((invoked==="ctx"?"context":invoked)!==command)return;const flag=unknownOption.split("=",1)[0],indices=invocationArgv.flatMap((token,index2)=>token===flag||token.startsWith(`${flag}=`)?[index2]:[]);if(indices.length!==1)return;const index=indices[0],correction=readOptionCorrection(command,flag,invocationArgv[index],invocationArgv[index+1]);if(!correction)return;const{replacement,consumed,conflicts}=correction;if(!invocationArgv.some(argument=>conflicts.includes(argument.split("=",1)[0])))return[...invocationArgv.slice(0,index),...replacement,...invocationArgv.slice(index+consumed)]}function isReadProjectionRecoveryFlag(flag){const normalized=flag.split("=",1)[0].replaceAll("_","-");return READ_PROJECTION_FLAGS.has(normalized)||normalized.length>=5&&[...READ_PROJECTION_FLAGS].some(candidate=>candidate.startsWith(normalized))}function isCompatibleRecoveryFlag(requested,candidate){const unknownFlag=requested.split("=",1)[0].replaceAll("_","-");return isReadProjectionRecoveryFlag(unknownFlag)?!MUTATION_RECEIPT_FLAGS.has(candidate):MUTATION_RECEIPT_FLAGS.has(unknownFlag)?!isReadProjectionRecoveryFlag(candidate):!0}function normalizeMissingFlag(label){return label.trim().match(/--[a-z0-9][a-z0-9_-]*/i)?.[0]?.replaceAll("_","-").toLowerCase()}function resolveRecoveryCommandName(invocationArgv){if(!(!Array.isArray(invocationArgv)||invocationArgv.length===0))return parseBootstrapCommandName(invocationArgv)}function resolveMissingOptionPlaceholder(commandName,missingLabel){const flag=normalizeMissingFlag(missingLabel);if(!flag)return;const contract=resolveSubcommandFlagContractsForCommand(commandName).find(entry=>entry.flag===flag||entry.aliases?.includes(flag));return contract?contract.value_type==="boolean"?null:`<${contract.value_name??"value"}>`:"<value>"}function renderMissingOptionRetry(invocationArgv,commandName,missingLabels){const retry=[...invocationArgv],terminatorIndex=retry.indexOf("--");let insertionIndex=terminatorIndex<0?retry.length:terminatorIndex;for(const label of missingLabels){const flag=normalizeMissingFlag(label);if(!flag||retry.slice(0,insertionIndex).some(token=>token===flag||token.startsWith(`${flag}=`)))continue;const placeholder=resolveMissingOptionPlaceholder(commandName,flag),recoveredOption=placeholder?[flag,placeholder]:[flag];retry.splice(insertionIndex,0,...recoveredOption),insertionIndex+=recoveredOption.length}return retry.length===invocationArgv.length?void 0:renderPmCommand(retry)}export{isCompatibleRecoveryFlag,isReadProjectionRecoveryFlag,renderMissingOptionRetry,resolveLinkedResourcePositionalRecovery,resolveMissingOptionPlaceholder,resolveReadOptionRetryArgs,resolveRecoveryCommandName};
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]="7eec77b5-0b24-5f0f-967c-a75907f4cd66")}catch{}})();import{renderPmCommand}from"../command-line.js";import{resolveLinkedResourcePositionalRecovery}from"./linked-resource-recovery.js";import{resolveSubcommandFlagContractsForCommand}from"../cli-contracts/flag-contracts.js";import{parseBootstrapCommandName}from"../cli-contracts/bootstrap-command-scanner.js";import{READ_OUTPUT_DIMENSION_FLAGS,READ_OUTPUT_COMPOSITION_FLAGS}from"../read-output/options.js";import{resolvePmCommandOperation}from"../cli-contracts/command-aliases.js";const READ_PROJECTION_FLAGS=new Set([...Object.values(READ_OUTPUT_DIMENSION_FLAGS),...READ_OUTPUT_COMPOSITION_FLAGS,"--full","--brief","--compact","--summary","--fields","--section","--token-budget"]),MUTATION_RECEIPT_FLAGS=new Set(["--full-changed-fields","--no-changed-fields","--id-only"]);function resolveLifecycleVerbRecovery(verb,availablePaths){if(!["block","unblock"].includes(verb)||availablePaths.includes(verb)||!availablePaths.includes("update"))return;const flags=new Set(resolveSubcommandFlagContractsForCommand("update").map(entry=>entry.flag));if((verb==="block"?["--blocked-by","--blocked-reason"]:["--unset","--unblock-note"]).every(flag=>flags.has(flag)))return verb==="block"?{examples:[["update","<item-id>","--blocked-by","<blocker-id>","--blocked-reason","<reason>"]],nextSteps:["Choose the actual item and blocker identifiers before running update. --blocked-by records the blocker field and its blocked_by relationship."]}:{examples:[["update","<item-id>","--unset","blocked-by","--unset","blocked-reason","--unblock-note","<note>"]],nextSteps:["Inspect the item's blockers before running update. --unset blocked-by removes the blocker field and all blocked_by relationships; --unset blocked-reason clears the stale reason. --unblock-note alone records a note and does not unblock the item.","If your project also uses a blocked lifecycle status, choose its appropriate next status separately with update --status."]}}function activitySinceCorrection(token,next){const inline=token.includes("="),value=inline?token.slice(token.indexOf("=")+1):next;if(!(!value||value.startsWith("--")))return{consumed:inline?1:2,replacement:["--from",value],conflicts:["--from"]}}function readOptionCorrection(command,flag,token,next){if(flag==="--since"&&command==="activity")return activitySinceCorrection(token,next);if(flag==="--full"&&command==="context"&&token===flag)return{consumed:1,replacement:["--depth","full"],conflicts:["--depth","--output-include","--fields","--section","--for"]};if(flag==="--depth"&&["list","search"].includes(command)){const inline=token.includes("=");return(inline?token.slice(token.indexOf("=")+1):next)!=="full"?void 0:{consumed:inline?1:2,replacement:["--full"],conflicts:["--full","--brief","--compact","--output-include","--fields","--for"]}}return flag==="--toon"&&token===flag?{consumed:1,replacement:["--output-format","toon"],conflicts:["--json","--format","--output-format","--stream"]}:void 0}function resolveReadOptionRetryArgs(commandName,invocationArgv,unknownOption){const command=commandName==="ctx"?"context":resolvePmCommandOperation(commandName);if(!["context","list","search","get","activity"].includes(command)||invocationArgv.includes("--"))return;const invoked=parseBootstrapCommandName(invocationArgv);if((invoked==="ctx"?"context":invoked)!==command)return;const flag=unknownOption.split("=",1)[0],indices=invocationArgv.flatMap((token,index2)=>token===flag||token.startsWith(`${flag}=`)?[index2]:[]);if(indices.length!==1)return;const index=indices[0],correction=readOptionCorrection(command,flag,invocationArgv[index],invocationArgv[index+1]);if(!correction)return;const{replacement,consumed,conflicts}=correction;if(!invocationArgv.some(argument=>conflicts.includes(argument.split("=",1)[0])))return[...invocationArgv.slice(0,index),...replacement,...invocationArgv.slice(index+consumed)]}function isReadProjectionRecoveryFlag(flag){const normalized=flag.split("=",1)[0].replaceAll("_","-");return READ_PROJECTION_FLAGS.has(normalized)||normalized.length>=5&&[...READ_PROJECTION_FLAGS].some(candidate=>candidate.startsWith(normalized))}function isCompatibleRecoveryFlag(requested,candidate){const unknownFlag=requested.split("=",1)[0].replaceAll("_","-");return isReadProjectionRecoveryFlag(unknownFlag)?!MUTATION_RECEIPT_FLAGS.has(candidate):MUTATION_RECEIPT_FLAGS.has(unknownFlag)?!isReadProjectionRecoveryFlag(candidate):!0}function normalizeMissingFlag(label){return label.trim().match(/--[a-z0-9][a-z0-9_-]*/i)?.[0]?.replaceAll("_","-").toLowerCase()}function resolveRecoveryCommandName(invocationArgv){if(!(!Array.isArray(invocationArgv)||invocationArgv.length===0))return parseBootstrapCommandName(invocationArgv)}function resolveMissingOptionPlaceholder(commandName,missingLabel){const flag=normalizeMissingFlag(missingLabel);if(!flag)return;const contract=resolveSubcommandFlagContractsForCommand(commandName).find(entry=>entry.flag===flag||entry.aliases?.includes(flag));return contract?contract.value_type==="boolean"?null:`<${contract.value_name??"value"}>`:"<value>"}function renderMissingOptionRetry(invocationArgv,commandName,missingLabels){const retry=[...invocationArgv],terminatorIndex=retry.indexOf("--");let insertionIndex=terminatorIndex<0?retry.length:terminatorIndex;for(const label of missingLabels){const flag=normalizeMissingFlag(label);if(!flag||retry.slice(0,insertionIndex).some(token=>token===flag||token.startsWith(`${flag}=`)))continue;const placeholder=resolveMissingOptionPlaceholder(commandName,flag),recoveredOption=placeholder?[flag,placeholder]:[flag];retry.splice(insertionIndex,0,...recoveredOption),insertionIndex+=recoveredOption.length}return retry.length===invocationArgv.length?void 0:renderPmCommand(retry)}export{isCompatibleRecoveryFlag,isReadProjectionRecoveryFlag,renderMissingOptionRetry,resolveLifecycleVerbRecovery,resolveLinkedResourcePositionalRecovery,resolveMissingOptionPlaceholder,resolveReadOptionRetryArgs,resolveRecoveryCommandName};
2
2
  //# sourceMappingURL=command-recovery.js.map
@@ -1,4 +1,10 @@
1
+ import type { GlobalOptions } from "../core/shared/command-types.js";
1
2
  export { quoteWindowsCommandArg,quoteCommandArg,renderPmCommand } from "../core/shared/command-line.js";
3
+ type CommandScope = Pick<GlobalOptions,"path" | "noExtensions">;
4
+ /** Retain caller scope before runtime dispatch resolves its working storage path. */
5
+ export declare function capturePmCommandScope(options:CommandScope):void;
6
+ /** Build copy-safe tracker and extension arguments, preserving explicit spelling and omitting the implicit cwd tracker. */
7
+ export declare function resolvePmCommandScopeArgs(options:CommandScope,cwd?:string):string[];
2
8
  /** Recognize the leading redaction command after global options, even before flag validation succeeds. */
3
9
  export declare function isHistoryRedactInvocation(argv:readonly string[]):boolean;
4
10
  /**
@@ -1,2 +1,2 @@
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]="98cde1d6-d5dd-56b9-89f9-51f5d08221d1")}catch{}})();import{findBootstrapCommandTokenIndex}from"./cli-contracts/bootstrap-command-scanner.js";import{quoteWindowsCommandArg,quoteCommandArg,renderPmCommand}from"../core/shared/command-line.js";const HISTORY_REDACT_SENSITIVE_FLAGS=new Set(["--literal","--regex","--replacement"]);function isHistoryRedactInvocation(argv){const rootIndex=findBootstrapCommandTokenIndex(argv);if(rootIndex===void 0)return!1;if(argv[rootIndex]==="history-redact")return!0;if(argv[rootIndex]!=="history")return!1;const operationArgs=argv.slice(rootIndex+1),operationIndex=findBootstrapCommandTokenIndex(operationArgs);return operationIndex!==void 0&&operationArgs[operationIndex]==="redact"}function redactSensitiveCommandArgs(argv){if(!isHistoryRedactInvocation(argv))return[...argv];const redacted=[];let redactNext=!1;for(const token of argv){if(redactNext){redacted.push("[redacted]"),redactNext=!1;continue}redactNext=!1;const equalsIndex=token.indexOf("="),flag=equalsIndex>=0?token.slice(0,equalsIndex):token;if(!HISTORY_REDACT_SENSITIVE_FLAGS.has(flag)){redacted.push(token);continue}if(equalsIndex>=0){redacted.push(`${flag}=[redacted]`);continue}redacted.push(flag),redactNext=!0}return redacted}export{isHistoryRedactInvocation,quoteCommandArg,quoteWindowsCommandArg,redactSensitiveCommandArgs,renderPmCommand};
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]="08181915-ead8-51bc-a078-9d97b9048f37")}catch{}})();import{findBootstrapCommandTokenIndex}from"./cli-contracts/bootstrap-command-scanner.js";import path from"node:path";import{resolveImplicitPmRoot,resolvePmRoot,resolveWorkspaceRoot}from"../core/store/paths.js";import{isPathWithinDirectory}from"../core/fs/path-utils.js";import{quoteWindowsCommandArg,quoteCommandArg,renderPmCommand}from"../core/shared/command-line.js";const requestedPaths=new WeakMap;function capturePmCommandScope(options){requestedPaths.set(options,options.path)}function environmentCommandScope(cwd){if(!process.env.PM_PATH?.trim())return;const resolved=resolvePmRoot(cwd);return isPathWithinDirectory(resolveWorkspaceRoot(resolved),cwd)&&resolved===resolveImplicitPmRoot(cwd)?void 0:path.relative(cwd,resolved)||"."}function resolvePmCommandScopeArgs(options,cwd=process.cwd()){const selected=(requestedPaths.has(options)?requestedPaths.get(options):options.path)||environmentCommandScope(cwd),args=selected?["--pm-path",selected]:[];return options.noExtensions&&args.push("--no-extensions"),args}const HISTORY_REDACT_SENSITIVE_FLAGS=new Set(["--literal","--regex","--replacement"]);function isHistoryRedactInvocation(argv){const rootIndex=findBootstrapCommandTokenIndex(argv);if(rootIndex===void 0)return!1;if(argv[rootIndex]==="history-redact")return!0;if(argv[rootIndex]!=="history")return!1;const operationArgs=argv.slice(rootIndex+1),operationIndex=findBootstrapCommandTokenIndex(operationArgs);return operationIndex!==void 0&&operationArgs[operationIndex]==="redact"}function redactSensitiveCommandArgs(argv){if(!isHistoryRedactInvocation(argv))return[...argv];const redacted=[];let redactNext=!1;for(const token of argv){if(redactNext){redacted.push("[redacted]"),redactNext=!1;continue}redactNext=!1;const equalsIndex=token.indexOf("="),flag=equalsIndex>=0?token.slice(0,equalsIndex):token;if(!HISTORY_REDACT_SENSITIVE_FLAGS.has(flag)){redacted.push(token);continue}if(equalsIndex>=0){redacted.push(`${flag}=[redacted]`);continue}redacted.push(flag),redactNext=!0}return redacted}export{capturePmCommandScope,isHistoryRedactInvocation,quoteCommandArg,quoteWindowsCommandArg,redactSensitiveCommandArgs,renderPmCommand,resolvePmCommandScopeArgs};
2
2
  //# sourceMappingURL=command-line.js.map