@unbrained/pm-cli 2026.10.26 → 2026.10.27

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 (122) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +16 -1
  3. package/dist/cli/register-list-query.js +5 -5
  4. package/dist/cli-bundle/bundle-manifest.json +1 -1
  5. package/dist/cli-bundle/chunks/{chunk-MWCG25PO.js → chunk-2XUDAQK5.js} +2 -2
  6. package/dist/cli-bundle/chunks/{chunk-Y42DYMZX.js → chunk-32QK43XG.js} +2 -2
  7. package/dist/cli-bundle/chunks/{chunk-T7T4WLUY.js → chunk-34OQP43K.js} +3 -3
  8. package/dist/cli-bundle/chunks/{chunk-ZLVFUZI4.js → chunk-5PTMQBKJ.js} +30 -30
  9. package/dist/cli-bundle/chunks/{chunk-NGKTROAO.js → chunk-EKV5GP6P.js} +4 -4
  10. package/dist/cli-bundle/chunks/{chunk-OCDRHIVQ.js → chunk-F26MRQZY.js} +3 -3
  11. package/dist/cli-bundle/chunks/{chunk-XAIR53QZ.js → chunk-H434DKYU.js} +2 -2
  12. package/dist/cli-bundle/chunks/{chunk-TGOG5BFM.js → chunk-HIX2OMEZ.js} +2 -2
  13. package/dist/cli-bundle/chunks/{chunk-7UDQAINZ.js → chunk-NNIYQHYT.js} +2 -2
  14. package/dist/cli-bundle/chunks/chunk-O3LPT34G.js +20 -0
  15. package/dist/cli-bundle/chunks/{chunk-Z35XAHUN.js → chunk-OQOEBWHU.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-UF6EXZSP.js → chunk-Q55KZDNF.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-VS2IIV3F.js → chunk-QQYLNHZK.js} +5 -5
  18. package/dist/cli-bundle/chunks/chunk-SPPHDVZE.js +2 -0
  19. package/dist/cli-bundle/chunks/chunk-UHKN6TJM.js +114 -0
  20. package/dist/cli-bundle/chunks/{chunk-ZT64RDMF.js → chunk-X5TMR7KC.js} +2 -2
  21. package/dist/cli-bundle/chunks/{chunk-YJBIPNDL.js → chunk-XERBUA6A.js} +2 -2
  22. package/dist/cli-bundle/chunks/indexed-receipt-blobs-63WYG2PY.js +4 -0
  23. package/dist/cli-bundle/chunks/{mutation-admission-VTNV6JV2.js → mutation-admission-L3A6FSZ7.js} +2 -2
  24. package/dist/cli-bundle/chunks/{register-list-query-LZDWUZS4.js → register-list-query-YSQ7UTFI.js} +9 -9
  25. package/dist/cli-bundle/chunks/{register-mutation-M2A7PH42.js → register-mutation-6HRXYASW.js} +2 -2
  26. package/dist/cli-bundle/chunks/{register-operations-E7P2JTXM.js → register-operations-4O3YOYXF.js} +2 -2
  27. package/dist/cli-bundle/chunks/{register-setup-DOV7KGSH.js → register-setup-3WAXNDMY.js} +2 -2
  28. package/dist/cli-bundle/chunks/{settlement-hook-SVD6CO7U.js → settlement-hook-CRW6PVQK.js} +2 -2
  29. package/dist/cli-bundle/chunks/{stage-LYLEOAQB.js → stage-I46WD4EN.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-WDWHUJQW.js → chunk-4TXZBGOR.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/chunk-EGN2HFRU.js +2 -0
  32. package/dist/cli-bundle/focused-chunks/{chunk-IF6C43IP.js → chunk-HWD63G54.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/{chunk-NE27VCU7.js → chunk-J67PFM3O.js} +2 -2
  34. package/dist/cli-bundle/focused-chunks/{chunk-PK5FJIVA.js → chunk-MVY6JDIH.js} +2 -2
  35. package/dist/cli-bundle/focused-chunks/{chunk-UP765R2V.js → chunk-R2MTHS2H.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/chunk-SM2KGD4J.js +79 -0
  37. package/dist/cli-bundle/focused-chunks/{chunk-226XKW3W.js → chunk-SYL73MEI.js} +3 -3
  38. package/dist/cli-bundle/focused-chunks/{chunk-CSCZYSNZ.js → chunk-TAFMNTA5.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/{chunk-I7H3XF25.js → chunk-TGUOEOKP.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/chunk-U4UBQBS7.js +2 -0
  41. package/dist/cli-bundle/focused-chunks/{chunk-D5YQ4KAE.js → chunk-WDKZB3V6.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/{chunk-KERJNFXY.js → chunk-XK3XMZM4.js} +2 -2
  43. package/dist/cli-bundle/focused-chunks/{chunk-ADSBGYLW.js → chunk-Y57A4ZDI.js} +55 -55
  44. package/dist/cli-bundle/focused-chunks/{chunk-BL77VCRB.js → chunk-YC6NCPLK.js} +2 -2
  45. package/dist/cli-bundle/focused-chunks/chunk-ZA6AEYIM.js +2 -0
  46. package/dist/cli-bundle/focused-chunks/{chunk-YTEC2EPM.js → chunk-ZH7GTEWL.js} +3 -3
  47. package/dist/cli-bundle/focused-chunks/indexed-receipt-blobs-GAFC52LQ.js +4 -0
  48. package/dist/cli-bundle/focused-chunks/{mutation-admission-L42E3U5U.js → mutation-admission-ENBFMV2X.js} +2 -2
  49. package/dist/cli-bundle/focused-chunks/{settlement-hook-3CADO4XZ.js → settlement-hook-PUYJJDFL.js} +2 -2
  50. package/dist/cli-bundle/focused-chunks/{stage-TUQHWU7N.js → stage-MAWZTM2H.js} +2 -2
  51. package/dist/cli-bundle/main.js +2 -2
  52. package/dist/cli-bundle/sdk-authoring.js +1 -1
  53. package/dist/cli-bundle/sdk-contracts.js +2 -2
  54. package/dist/cli-bundle/sdk-core.js +33 -33
  55. package/dist/cli-bundle/sdk-governance.js +1 -1
  56. package/dist/cli-bundle/sdk-graph.js +1 -1
  57. package/dist/cli-bundle/sdk-merge.js +57 -57
  58. package/dist/cli-bundle/sdk-query.js +1 -1
  59. package/dist/cli-bundle/sdk-runtime.js +1 -1
  60. package/dist/cli-bundle/sdk-testing.js +1 -1
  61. package/dist/cli-bundle/sdk.js +3 -3
  62. package/dist/core/history/event-index.d.ts +6 -0
  63. package/dist/core/history/event-index.js +7 -6
  64. package/dist/core/history/read.d.ts +3 -1
  65. package/dist/core/history/read.js +1 -1
  66. package/dist/mcp/tool-definitions.js +1 -1
  67. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  68. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
  69. package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
  70. package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
  71. package/dist/sdk/cli-contracts/tool-schema.js +1 -1
  72. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  73. package/dist/sdk/merge/indexed-receipt-blobs.d.ts +3 -1
  74. package/dist/sdk/merge/indexed-receipt-blobs.js +2 -2
  75. package/dist/sdk/merge/receipt-file-boundary.d.ts +2 -0
  76. package/dist/sdk/merge/receipt-file-boundary.js +1 -1
  77. package/dist/sdk/merge/receipts.js +2 -2
  78. package/dist/sdk/mutation-events.d.ts +6 -0
  79. package/dist/sdk/mutation-events.js +1 -1
  80. package/dist/sdk/public-surface.json +1 -1
  81. package/dist/sdk/runtime-extended-actions.js +1 -1
  82. package/dist/sdk/test/execution.js +2 -2
  83. package/dist/sdk/test/receipt-index-snapshot.d.ts +2 -0
  84. package/dist/sdk/test/receipt-index-snapshot.js +2 -0
  85. package/dist/sdk/test/workspace-snapshot.d.ts +1 -1
  86. package/dist/sdk/test/workspace-snapshot.js +1 -1
  87. package/docs/PERFORMANCE.md +21 -6
  88. package/docs/RELEASING.md +11 -0
  89. package/docs/SDK_CONTEXT_COORDINATION.md +35 -4
  90. package/docs/TESTING.md +14 -1
  91. package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
  92. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
  93. package/marketplace.json +1 -1
  94. package/package.json +1 -1
  95. package/packages/pm-beads/package.json +1 -1
  96. package/packages/pm-calendar/package.json +1 -1
  97. package/packages/pm-command-kit/package.json +1 -1
  98. package/packages/pm-digital-twin/package.json +1 -1
  99. package/packages/pm-governance-audit/package.json +1 -1
  100. package/packages/pm-guide-shell/package.json +1 -1
  101. package/packages/pm-kanban/package.json +1 -1
  102. package/packages/pm-lifecycle-hooks/package.json +1 -1
  103. package/packages/pm-linked-test-adapters/package.json +1 -1
  104. package/packages/pm-search-advanced/package.json +1 -1
  105. package/packages/pm-templates/package.json +1 -1
  106. package/packages/pm-todos/package.json +1 -1
  107. package/packages/pm-vcs/package.json +1 -1
  108. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  109. package/plugins/pm-claude/package.json +1 -1
  110. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  111. package/plugins/pm-codex/package.json +1 -1
  112. package/plugins/pm-codex/plugin.json +1 -1
  113. package/runtime-dependencies.json +1 -1
  114. package/dist/cli-bundle/chunks/chunk-N6FTEILW.js +0 -20
  115. package/dist/cli-bundle/chunks/chunk-OUDR2HWR.js +0 -113
  116. package/dist/cli-bundle/chunks/chunk-RUKSEZE7.js +0 -2
  117. package/dist/cli-bundle/chunks/indexed-receipt-blobs-NWQIDTH7.js +0 -4
  118. package/dist/cli-bundle/focused-chunks/chunk-ABMNYWV6.js +0 -2
  119. package/dist/cli-bundle/focused-chunks/chunk-NFN2P4TW.js +0 -2
  120. package/dist/cli-bundle/focused-chunks/chunk-UHWTPOM4.js +0 -78
  121. package/dist/cli-bundle/focused-chunks/chunk-VVRXF4JO.js +0 -2
  122. package/dist/cli-bundle/focused-chunks/indexed-receipt-blobs-YFDNGHCM.js +0 -4
@@ -17,6 +17,8 @@ stream_offset:number;
17
17
  }
18
18
  /** Workspace and filtering controls for mutation-event reads. */
19
19
  export interface ListMutationEventsOptions {
20
+ /** Verify complete selected authoritative chains before filtering or pagination. */
21
+ verify?:boolean;
20
22
  /** Explicit tracker root, equivalent to global `--pm-path`. */
21
23
  pmRoot?:string;
22
24
  /** Working directory used to discover the nearest tracker. */
@@ -71,6 +73,10 @@ provenance?:HistoryProvenanceRow;
71
73
  }
72
74
  /** Bounded event page returned by {@link listMutationEvents}. */
73
75
  export interface MutationEventPage {
76
+ /** Chain verification is opt-in; content cache validation alone is not proof. */
77
+ integrity:"verified" | "unverified";
78
+ /** Complete selected authoritative streams checked when verification is requested. */
79
+ verified_streams?:number;
74
80
  /** Ordered mutation events. */
75
81
  events:MutationEvent[];
76
82
  /** Number of events in this page. */
@@ -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]="62e71554-f62d-55c5-811c-198f573d9426")}catch{}})();import{assertInitializedTracker}from"./environment/tracker-preflight.js";import{createHash}from"node:crypto";import{setTimeout as delay}from"node:timers/promises";import{readHistoryEventIndexPage,queryHistoryEventStreams,rebuildHistoryEventIndex}from"../core/history/event-index.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{stableStringify}from"../core/shared/serialization.js";import{toErrorMessage}from"../core/shared/primitives.js";import{resolvePmRoot}from"../core/store/paths.js";import{readSettings}from"../core/store/settings.js";import{parseHistoryProvenanceFilters,projectHistoryProvenance,resolveHistoryProvenanceDimensions,summarizeHistoryProvenance}from"./history-provenance.js";const MUTATION_EVENT_CURSOR_VERSION=1,MUTATION_EVENT_CURSOR_PATTERN=/^[A-Za-z0-9_-]+$/,DEFAULT_EVENT_LIMIT=100,MAX_EVENT_LIMIT=1e3,DEFAULT_FOLLOW_INTERVAL_MS=250,MUTATION_EVENT_WIRE_BUDGET=Object.freeze({batch_to_row_ratio:.6,fixture_events:200});function normalizeFilter(value){if(value===void 0)return;const values=typeof value=="string"?[value]:value,normalized=[...new Set(values.flatMap(entry=>entry.split(",")).map(entry=>entry.trim()).filter(Boolean))].sort((left,right)=>left.localeCompare(right));return normalized.length===0?void 0:normalized}function eventQueryFingerprint(options){return createHash("sha256").update(stableStringify({type:normalizeFilter(options.type),author:normalizeFilter(options.author),item:normalizeFilter(options.item),harness:normalizeFilter(options.harness),agent_instance:normalizeFilter(options.agentInstance),provenance:normalizeFilter(options.provenanceFilter)})).digest("hex").slice(0,24)}function encodeMutationEventCursor(event,fingerprint){const envelope={version:MUTATION_EVENT_CURSOR_VERSION,fingerprint,ts:event.entry.ts,stream_id:event.stream_id,stream_offset:event.stream_offset};return Buffer.from(JSON.stringify(envelope),"utf8").toString("base64url")}function isMutationEventCursorEnvelope(value,fingerprint){if(typeof value!="object"||value===null)return!1;const candidate=value;return[candidate.version===MUTATION_EVENT_CURSOR_VERSION,candidate.fingerprint===fingerprint,typeof candidate.ts=="string",typeof candidate.stream_id=="string",typeof candidate.stream_offset=="number",Number.isSafeInteger(candidate.stream_offset),Number(candidate.stream_offset)>=0].every(Boolean)}function decodeMutationEventCursor(cursor,fingerprint){const normalized=cursor.trim();if(normalized.length===0||normalized.length>4096||!MUTATION_EVENT_CURSOR_PATTERN.test(normalized))throw new PmCliError("Invalid mutation event cursor.",EXIT_CODE.USAGE,{code:"invalid_event_cursor"});let parsed;try{parsed=JSON.parse(Buffer.from(normalized,"base64url").toString("utf8"))}catch{throw new PmCliError("Invalid mutation event cursor.",EXIT_CODE.USAGE,{code:"invalid_event_cursor"})}if(!isMutationEventCursorEnvelope(parsed,fingerprint))throw new PmCliError("Mutation event cursor does not match this query.",EXIT_CODE.USAGE,{code:"event_cursor_query_mismatch"});return parsed}function parseMutationEventLimit(value){const limit=value??DEFAULT_EVENT_LIMIT;if(!Number.isSafeInteger(limit)||limit<0||limit>MAX_EVENT_LIMIT)throw new PmCliError(`Mutation event limit must be an integer from 0 to ${MAX_EVENT_LIMIT}.`,EXIT_CODE.USAGE,{code:"invalid_event_limit"});return limit}function isAbortError(error){return error instanceof Error&&error.name==="AbortError"}function resolveMutationEventStart(sinceValue,fingerprint){const since=sinceValue?.trim();if(!since)return{};if(MUTATION_EVENT_CURSOR_PATTERN.test(since))return{cursor:decodeMutationEventCursor(since,fingerprint)};const milliseconds=Date.parse(since);if(!Number.isFinite(milliseconds))throw new PmCliError("Mutation event --since must be an event cursor or ISO timestamp.",EXIT_CODE.USAGE,{code:"invalid_event_since"});return{sinceTimestamp:new Date(milliseconds).toISOString()}}async function resolveIndexedMutationEvents(pmRoot,query){const attempt=await readHistoryEventIndexPage(pmRoot,query);let indexed=attempt.result;if(indexed===null&&attempt.repair_needed)try{await rebuildHistoryEventIndex(pmRoot,{lockWaitMs:0})&&(indexed=(await readHistoryEventIndexPage(pmRoot,query)).result)}catch{}if(indexed===null)try{return{...await queryHistoryEventStreams(pmRoot,query),source:"authoritative_history"}}catch(error){throw error instanceof PmCliError?error:new PmCliError("Mutation events are unavailable because authoritative history could not be read.",EXIT_CODE.GENERIC_FAILURE,{code:"event_index_unavailable",why:toErrorMessage(error)})}return{...indexed,source:"derived_index"}}function resolveMutationEventCursorMode(value){const cursorMode=value??"batch";if(cursorMode!=="batch"&&cursorMode!=="row")throw new PmCliError("Mutation event cursor mode must be batch or row.",EXIT_CODE.USAGE,{code:"invalid_event_cursor_mode"});return cursorMode}async function listMutationEvents(options={}){const pmRoot=resolvePmRoot(options.cwd??process.cwd(),options.pmRoot);await assertInitializedTracker(pmRoot);const requestedLimit=parseMutationEventLimit(options.limit),cursorMode=resolveMutationEventCursorMode(options.cursorMode);if(options.full===!0&&options.provenance===!0)throw new PmCliError("Mutation event projections are mutually exclusive. Use --provenance or --full.",EXIT_CODE.USAGE);const settings=await readSettings(pmRoot),vocabulary=settings.agent_identity.identity_vocabulary,dimensions=resolveHistoryProvenanceDimensions(settings.agent_identity.harness_signals),provenancePredicates=parseHistoryProvenanceFilters({provenance:options.provenanceFilter},dimensions),harnesses=normalizeFilter(options.harness),fingerprint=eventQueryFingerprint(options),{cursor,sinceTimestamp}=resolveMutationEventStart(options.since,fingerprint),query={...cursor?{after_ts:cursor.ts,after_stream_id:cursor.stream_id,after_stream_offset:cursor.stream_offset}:sinceTimestamp?{since_ts:sinceTimestamp}:{},ops:normalizeFilter(options.type),authors:normalizeFilter(options.author),harnesses,harness_alias_authors:harnesses?Object.entries(vocabulary.aliases).filter(([,harness])=>harnesses.includes(harness)).map(([author])=>author):void 0,agent_instances:normalizeFilter(options.agentInstance),provenance:[...provenancePredicates].map(([dimension,values])=>({dimension,values:[...values]})),stream_ids:normalizeFilter(options.item),limit:requestedLimit},indexed=await resolveIndexedMutationEvents(pmRoot,query),events=indexed.events.map(event=>({...cursorMode==="row"?{cursor:encodeMutationEventCursor(event,fingerprint)}:{},item_id:event.stream_id,version:event.stream_offset+1,ts:event.entry.ts,author:event.entry.author,type:event.entry.op,...event.entry.message===void 0?{}:{message:event.entry.message},patch_count:event.entry.patch.length,...options.full===!0?{entry:event.entry}:{},...options.provenance===!0?{provenance:projectHistoryProvenance(event.entry,vocabulary,{itemId:event.stream_id,version:event.stream_offset+1})}:{}}));return{events,count:events.length,has_more:indexed.has_more,cursor_mode:cursorMode,...indexed.events.length===0?{}:{next_cursor:encodeMutationEventCursor(indexed.events[indexed.events.length-1],fingerprint)},source:indexed.source,...options.provenanceSummary===!0?{provenance_summary:summarizeHistoryProvenance(indexed.events.map(event=>event.entry),vocabulary,dimensions)}:{}}}async function*subscribeMutationEventBatches(options={}){const intervalMs=options.intervalMs??DEFAULT_FOLLOW_INTERVAL_MS;if(!Number.isSafeInteger(intervalMs)||intervalMs<10)throw new PmCliError("Mutation event follow interval must be an integer of at least 10ms.",EXIT_CODE.USAGE,{code:"invalid_event_follow_interval"});let cursor=options.since;for(;options.signal?.aborted!==!0;){const page=await listMutationEvents({...options,cursorMode:options.cursorMode??"batch",since:cursor});if(yield page.next_cursor===void 0&&cursor!==void 0?{...page,next_cursor:cursor}:page,page.events.length>0){cursor=page.next_cursor;continue}try{await delay(intervalMs,void 0,{signal:options.signal})}catch(error){if(isAbortError(error))return;throw error}}}async function*subscribeMutationEvents(options={}){for await(const page of subscribeMutationEventBatches({...options,cursorMode:"row"}))for(const event of page.events)yield event}const _testOnlyMutationEvents={decodeMutationEventCursor,encodeMutationEventCursor,eventQueryFingerprint,isAbortError,isMutationEventCursorEnvelope,parseMutationEventLimit,resolveMutationEventStart};export{MUTATION_EVENT_WIRE_BUDGET,_testOnlyMutationEvents,listMutationEvents,subscribeMutationEventBatches,subscribeMutationEvents};
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]="c583f859-9204-565b-b143-59aba53c3e9c")}catch{}})();import{assertInitializedTracker}from"./environment/tracker-preflight.js";import{createHash}from"node:crypto";import{setTimeout as delay}from"node:timers/promises";import{readHistoryEventIndexPage,queryHistoryEventStreams,rebuildHistoryEventIndex}from"../core/history/event-index.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{stableStringify}from"../core/shared/serialization.js";import{toErrorMessage}from"../core/shared/primitives.js";import{resolvePmRoot}from"../core/store/paths.js";import{readSettings}from"../core/store/settings.js";import{parseHistoryProvenanceFilters,projectHistoryProvenance,resolveHistoryProvenanceDimensions,summarizeHistoryProvenance}from"./history-provenance.js";const MUTATION_EVENT_CURSOR_VERSION=1,MUTATION_EVENT_CURSOR_PATTERN=/^[A-Za-z0-9_-]+$/,DEFAULT_EVENT_LIMIT=100,MAX_EVENT_LIMIT=1e3,DEFAULT_FOLLOW_INTERVAL_MS=250,MUTATION_EVENT_WIRE_BUDGET=Object.freeze({batch_to_row_ratio:.6,fixture_events:200});function normalizeFilter(value){if(value===void 0)return;const values=typeof value=="string"?[value]:value,normalized=[...new Set(values.flatMap(entry=>entry.split(",")).map(entry=>entry.trim()).filter(Boolean))].sort((left,right)=>left.localeCompare(right));return normalized.length===0?void 0:normalized}function eventQueryFingerprint(options){return createHash("sha256").update(stableStringify({type:normalizeFilter(options.type),author:normalizeFilter(options.author),item:normalizeFilter(options.item),harness:normalizeFilter(options.harness),agent_instance:normalizeFilter(options.agentInstance),provenance:normalizeFilter(options.provenanceFilter)})).digest("hex").slice(0,24)}function encodeMutationEventCursor(event,fingerprint){const envelope={version:MUTATION_EVENT_CURSOR_VERSION,fingerprint,ts:event.entry.ts,stream_id:event.stream_id,stream_offset:event.stream_offset};return Buffer.from(JSON.stringify(envelope),"utf8").toString("base64url")}function isMutationEventCursorEnvelope(value,fingerprint){if(typeof value!="object"||value===null)return!1;const candidate=value;return[candidate.version===MUTATION_EVENT_CURSOR_VERSION,candidate.fingerprint===fingerprint,typeof candidate.ts=="string",typeof candidate.stream_id=="string",typeof candidate.stream_offset=="number",Number.isSafeInteger(candidate.stream_offset),Number(candidate.stream_offset)>=0].every(Boolean)}function decodeMutationEventCursor(cursor,fingerprint){const normalized=cursor.trim();if(normalized.length===0||normalized.length>4096||!MUTATION_EVENT_CURSOR_PATTERN.test(normalized))throw new PmCliError("Invalid mutation event cursor.",EXIT_CODE.USAGE,{code:"invalid_event_cursor"});let parsed;try{parsed=JSON.parse(Buffer.from(normalized,"base64url").toString("utf8"))}catch{throw new PmCliError("Invalid mutation event cursor.",EXIT_CODE.USAGE,{code:"invalid_event_cursor"})}if(!isMutationEventCursorEnvelope(parsed,fingerprint))throw new PmCliError("Mutation event cursor does not match this query.",EXIT_CODE.USAGE,{code:"event_cursor_query_mismatch"});return parsed}function parseMutationEventLimit(value){const limit=value??DEFAULT_EVENT_LIMIT;if(!Number.isSafeInteger(limit)||limit<0||limit>MAX_EVENT_LIMIT)throw new PmCliError(`Mutation event limit must be an integer from 0 to ${MAX_EVENT_LIMIT}.`,EXIT_CODE.USAGE,{code:"invalid_event_limit"});return limit}function isAbortError(error){return error instanceof Error&&error.name==="AbortError"}function resolveMutationEventStart(sinceValue,fingerprint){const since=sinceValue?.trim();if(!since)return{};if(MUTATION_EVENT_CURSOR_PATTERN.test(since))return{cursor:decodeMutationEventCursor(since,fingerprint)};const milliseconds=Date.parse(since);if(!Number.isFinite(milliseconds))throw new PmCliError("Mutation event --since must be an event cursor or ISO timestamp.",EXIT_CODE.USAGE,{code:"invalid_event_since"});return{sinceTimestamp:new Date(milliseconds).toISOString()}}async function resolveIndexedMutationEvents(pmRoot,query){if(query.verify)return queryAuthoritativeMutationEvents(pmRoot,query);const attempt=await readHistoryEventIndexPage(pmRoot,query);let indexed=attempt.result;if(indexed===null&&attempt.repair_needed)try{await rebuildHistoryEventIndex(pmRoot,{lockWaitMs:0})&&(indexed=(await readHistoryEventIndexPage(pmRoot,query)).result)}catch{}return indexed===null?queryAuthoritativeMutationEvents(pmRoot,query):{...indexed,source:"derived_index"}}async function queryAuthoritativeMutationEvents(pmRoot,query){try{return{...await queryHistoryEventStreams(pmRoot,query),source:"authoritative_history"}}catch(error){throw error instanceof PmCliError?error:new PmCliError("Mutation events are unavailable because authoritative history could not be read.",EXIT_CODE.GENERIC_FAILURE,{code:"event_index_unavailable",why:toErrorMessage(error)})}}function resolveMutationEventCursorMode(value){const cursorMode=value??"batch";if(cursorMode!=="batch"&&cursorMode!=="row")throw new PmCliError("Mutation event cursor mode must be batch or row.",EXIT_CODE.USAGE,{code:"invalid_event_cursor_mode"});return cursorMode}async function listMutationEvents(options={}){const pmRoot=resolvePmRoot(options.cwd??process.cwd(),options.pmRoot);await assertInitializedTracker(pmRoot);const requestedLimit=parseMutationEventLimit(options.limit),cursorMode=resolveMutationEventCursorMode(options.cursorMode);if(options.full===!0&&options.provenance===!0)throw new PmCliError("Mutation event projections are mutually exclusive. Use --provenance or --full.",EXIT_CODE.USAGE);const settings=await readSettings(pmRoot),vocabulary=settings.agent_identity.identity_vocabulary,dimensions=resolveHistoryProvenanceDimensions(settings.agent_identity.harness_signals),provenancePredicates=parseHistoryProvenanceFilters({provenance:options.provenanceFilter},dimensions),harnesses=normalizeFilter(options.harness),fingerprint=eventQueryFingerprint(options),{cursor,sinceTimestamp}=resolveMutationEventStart(options.since,fingerprint),query={verify:options.verify===!0,...cursor?{after_ts:cursor.ts,after_stream_id:cursor.stream_id,after_stream_offset:cursor.stream_offset}:sinceTimestamp?{since_ts:sinceTimestamp}:{},ops:normalizeFilter(options.type),authors:normalizeFilter(options.author),harnesses,harness_alias_authors:harnesses?Object.entries(vocabulary.aliases).filter(([,harness])=>harnesses.includes(harness)).map(([author])=>author):void 0,agent_instances:normalizeFilter(options.agentInstance),provenance:[...provenancePredicates].map(([dimension,values])=>({dimension,values:[...values]})),stream_ids:normalizeFilter(options.item),limit:requestedLimit},indexed=await resolveIndexedMutationEvents(pmRoot,query),events=indexed.events.map(event=>({...cursorMode==="row"?{cursor:encodeMutationEventCursor(event,fingerprint)}:{},item_id:event.stream_id,version:event.stream_offset+1,ts:event.entry.ts,author:event.entry.author,type:event.entry.op,...event.entry.message===void 0?{}:{message:event.entry.message},patch_count:event.entry.patch.length,...options.full===!0?{entry:structuredClone(event.recorded_entry??event.entry)}:{},...options.provenance===!0?{provenance:projectHistoryProvenance(event.entry,vocabulary,{itemId:event.stream_id,version:event.stream_offset+1})}:{}}));return{integrity:options.verify===!0?"verified":"unverified",...indexed.verified_streams===void 0?{}:{verified_streams:indexed.verified_streams},events,count:events.length,has_more:indexed.has_more,cursor_mode:cursorMode,...indexed.events.length===0?{}:{next_cursor:encodeMutationEventCursor(indexed.events[indexed.events.length-1],fingerprint)},source:indexed.source,...options.provenanceSummary===!0?{provenance_summary:summarizeHistoryProvenance(indexed.events.map(event=>event.entry),vocabulary,dimensions)}:{}}}async function*subscribeMutationEventBatches(options={}){const intervalMs=options.intervalMs??DEFAULT_FOLLOW_INTERVAL_MS;if(!Number.isSafeInteger(intervalMs)||intervalMs<10)throw new PmCliError("Mutation event follow interval must be an integer of at least 10ms.",EXIT_CODE.USAGE,{code:"invalid_event_follow_interval"});let cursor=options.since;for(;options.signal?.aborted!==!0;){const page=await listMutationEvents({...options,cursorMode:options.cursorMode??"batch",since:cursor});if(yield page.next_cursor===void 0&&cursor!==void 0?{...page,next_cursor:cursor}:page,page.events.length>0){cursor=page.next_cursor;continue}try{await delay(intervalMs,void 0,{signal:options.signal})}catch(error){if(isAbortError(error))return;throw error}}}async function*subscribeMutationEvents(options={}){for await(const page of subscribeMutationEventBatches({...options,cursorMode:"row"}))for(const event of page.events)yield event}const _testOnlyMutationEvents={decodeMutationEventCursor,encodeMutationEventCursor,eventQueryFingerprint,isAbortError,isMutationEventCursorEnvelope,parseMutationEventLimit,resolveMutationEventStart};export{MUTATION_EVENT_WIRE_BUDGET,_testOnlyMutationEvents,listMutationEvents,subscribeMutationEventBatches,subscribeMutationEvents};
2
2
  //# sourceMappingURL=mutation-events.js.map