@unbrained/pm-cli 2026.10.3 → 2026.10.5

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 (742) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +28 -2
  3. package/dist/cli/after-command-context-usage.js +1 -1
  4. package/dist/cli/argv-utils.js +1 -1
  5. package/dist/cli/bootstrap-args.js +1 -1
  6. package/dist/cli/bundle-integrity.js +2 -2
  7. package/dist/cli/command-namespaces.js +1 -1
  8. package/dist/cli/commander-usage.d.ts +1 -1
  9. package/dist/cli/commander-usage.js +7 -4
  10. package/dist/cli/commands/annotations/comments.js +1 -1
  11. package/dist/cli/commands/annotations/docs.js +1 -1
  12. package/dist/cli/commands/annotations/files.js +1 -1
  13. package/dist/cli/commands/annotations/learnings.js +1 -1
  14. package/dist/cli/commands/annotations/notes.js +1 -1
  15. package/dist/cli/commands/extension/describe.js +1 -1
  16. package/dist/cli/commands/extension/extension.js +1 -1
  17. package/dist/cli/commands/extension/scaffold.js +1 -1
  18. package/dist/cli/commands/extension/shared.js +1 -1
  19. package/dist/cli/commands/governance/gc.js +1 -1
  20. package/dist/cli/commands/governance/health.js +1 -1
  21. package/dist/cli/commands/governance/telemetry.js +1 -1
  22. package/dist/cli/commands/governance/validate.js +1 -1
  23. package/dist/cli/commands/history/activity.js +1 -1
  24. package/dist/cli/commands/history/history-compact.js +1 -1
  25. package/dist/cli/commands/history/history-redact.js +1 -1
  26. package/dist/cli/commands/history/history-repair.js +1 -1
  27. package/dist/cli/commands/history/history.js +1 -1
  28. package/dist/cli/commands/history/restore.js +1 -1
  29. package/dist/cli/commands/lifecycle/append.js +1 -1
  30. package/dist/cli/commands/lifecycle/claim.js +1 -1
  31. package/dist/cli/commands/lifecycle/close-many.js +1 -1
  32. package/dist/cli/commands/lifecycle/close.js +1 -1
  33. package/dist/cli/commands/lifecycle/copy.js +1 -1
  34. package/dist/cli/commands/lifecycle/create.js +1 -1
  35. package/dist/cli/commands/lifecycle/delete.js +1 -1
  36. package/dist/cli/commands/lifecycle/focus.js +1 -1
  37. package/dist/cli/commands/lifecycle/plan.js +1 -1
  38. package/dist/cli/commands/lifecycle/update-many.js +1 -1
  39. package/dist/cli/commands/lifecycle/update.js +1 -1
  40. package/dist/cli/commands/query/aggregate.js +1 -1
  41. package/dist/cli/commands/query/context.js +1 -1
  42. package/dist/cli/commands/query/deps.js +1 -1
  43. package/dist/cli/commands/query/duplicates.js +1 -1
  44. package/dist/cli/commands/query/eval.js +1 -1
  45. package/dist/cli/commands/query/get.js +1 -1
  46. package/dist/cli/commands/query/graph.js +1 -1
  47. package/dist/cli/commands/query/list.js +1 -1
  48. package/dist/cli/commands/query/next.js +1 -1
  49. package/dist/cli/commands/query/search.js +1 -1
  50. package/dist/cli/commands/query/stats.js +1 -1
  51. package/dist/cli/commands/test/test-all.js +1 -1
  52. package/dist/cli/commands/test/test-runs.js +1 -1
  53. package/dist/cli/commands/test/test.js +1 -1
  54. package/dist/cli/commands/workspace/config.js +1 -1
  55. package/dist/cli/commands/workspace/contracts.js +1 -1
  56. package/dist/cli/commands/workspace/init.js +1 -1
  57. package/dist/cli/commands/workspace/merge.js +1 -1
  58. package/dist/cli/commands/workspace/profile.js +1 -1
  59. package/dist/cli/commands/workspace/schema.js +1 -1
  60. package/dist/cli/commands/workspace/upgrade.js +1 -1
  61. package/dist/cli/context-intent-invocation.js +1 -1
  62. package/dist/cli/description-stdin.js +1 -1
  63. package/dist/cli/error-guidance.js +3 -1
  64. package/dist/cli/extension-command-help.js +5 -3
  65. package/dist/cli/extension-command-options.js +1 -1
  66. package/dist/cli/extension-recovery.js +1 -1
  67. package/dist/cli/help-content.js +5 -2
  68. package/dist/cli/help-json-payload.js +6 -3
  69. package/dist/cli/invocation-profile.js +2 -2
  70. package/dist/cli/main.js +5 -5
  71. package/dist/cli/migration-gates.js +1 -1
  72. package/dist/cli/option-values.js +1 -1
  73. package/dist/cli/public.js +1 -1
  74. package/dist/cli/register-annotations.js +1 -1
  75. package/dist/cli/register-assurance.js +1 -1
  76. package/dist/cli/register-files-lookup.js +1 -1
  77. package/dist/cli/register-history-activity.js +1 -1
  78. package/dist/cli/register-history-author.js +1 -1
  79. package/dist/cli/register-history-maintenance.js +2 -2
  80. package/dist/cli/register-list-query.js +10 -10
  81. package/dist/cli/register-mutation-options.js +1 -1
  82. package/dist/cli/register-mutation.js +2 -2
  83. package/dist/cli/register-operations.js +1 -1
  84. package/dist/cli/register-setup.js +1 -1
  85. package/dist/cli/register-structured-mutation.js +1 -1
  86. package/dist/cli/registration-helpers.js +1 -1
  87. package/dist/cli/runtime/activation.js +1 -1
  88. package/dist/cli/runtime/invocation-options.js +1 -1
  89. package/dist/cli/runtime/projection-retry.js +1 -1
  90. package/dist/cli/runtime/selection.js +1 -1
  91. package/dist/cli/runtime/telemetry-outcome.js +1 -1
  92. package/dist/cli/runtime-compatibility-boundary.d.ts +1 -1
  93. package/dist/cli/runtime-compatibility-boundary.js +4 -4
  94. package/dist/cli/schema/registration.js +2 -2
  95. package/dist/cli/schema-registration-helpers.js +1 -1
  96. package/dist/cli/search-refresh.js +1 -1
  97. package/dist/cli/stats-analytics-json.js +1 -1
  98. package/dist/cli/telemetry-flush.js +1 -1
  99. package/dist/cli-bundle/bundle-manifest.json +162 -162
  100. package/dist/cli-bundle/chunks/chunk-3CYOBJUK.js +3 -0
  101. package/dist/cli-bundle/chunks/chunk-5MNOWZPN.js +3 -0
  102. package/dist/cli-bundle/chunks/chunk-AJ7H6XUF.js +20 -0
  103. package/dist/cli-bundle/chunks/chunk-D332RXZ7.js +80 -0
  104. package/dist/cli-bundle/chunks/chunk-HRJ6G6ZG.js +31 -0
  105. package/dist/cli-bundle/chunks/chunk-KRVI56QE.js +6 -0
  106. package/dist/cli-bundle/chunks/chunk-N4YGSG6F.js +238 -0
  107. package/dist/cli-bundle/chunks/chunk-OOLYASYJ.js +2 -0
  108. package/dist/cli-bundle/chunks/chunk-R7CG2DB7.js +2 -0
  109. package/dist/cli-bundle/chunks/chunk-TGMONGWX.js +2 -0
  110. package/dist/cli-bundle/chunks/chunk-UZ7BIUCI.js +2 -0
  111. package/dist/cli-bundle/chunks/{chunk-44UGMMQ6.js → chunk-VZ63DEVJ.js} +3 -3
  112. package/dist/cli-bundle/chunks/chunk-WFZ4UEOB.js +2 -0
  113. package/dist/cli-bundle/chunks/chunk-YVBRASXO.js +8 -0
  114. package/dist/cli-bundle/chunks/{chunk-5XKF5SQV.js → chunk-Z66DWDAU.js} +91 -91
  115. package/dist/cli-bundle/chunks/{register-list-query-DYCGUQEW.js → register-list-query-75QXHIFH.js} +11 -11
  116. package/dist/cli-bundle/chunks/register-mutation-YS54SCHG.js +20 -0
  117. package/dist/cli-bundle/chunks/register-operations-6KHZQSYJ.js +2 -0
  118. package/dist/cli-bundle/chunks/register-setup-RTATEN2M.js +2 -0
  119. package/dist/cli-bundle/focused-chunks/{chunk-3BIYG72P.js → chunk-2CVX3KR3.js} +2 -2
  120. package/dist/cli-bundle/focused-chunks/chunk-5C3IDDW7.js +2 -0
  121. package/dist/cli-bundle/focused-chunks/{chunk-DBD4W4QP.js → chunk-ABV67XCC.js} +3 -3
  122. package/dist/cli-bundle/focused-chunks/chunk-B5RSLVE6.js +3 -0
  123. package/dist/cli-bundle/focused-chunks/chunk-C224METM.js +20 -0
  124. package/dist/cli-bundle/focused-chunks/chunk-CLDPTMQY.js +6 -0
  125. package/dist/cli-bundle/focused-chunks/chunk-DDRN42PB.js +8 -0
  126. package/dist/cli-bundle/focused-chunks/{chunk-EJN7DY3B.js → chunk-DOVTUKJQ.js} +2 -2
  127. package/dist/cli-bundle/focused-chunks/chunk-ECBOPEJE.js +75 -0
  128. package/dist/cli-bundle/focused-chunks/chunk-GITOYRUW.js +165 -0
  129. package/dist/cli-bundle/focused-chunks/chunk-GUIF3WVC.js +30 -0
  130. package/dist/cli-bundle/focused-chunks/chunk-LE4JUCRR.js +3 -0
  131. package/dist/cli-bundle/focused-chunks/{chunk-HFAW3FJQ.js → chunk-PSXFFQFT.js} +2 -2
  132. package/dist/cli-bundle/focused-chunks/chunk-RHIH6XIW.js +12 -0
  133. package/dist/cli-bundle/focused-chunks/chunk-UDYRVBOZ.js +2 -0
  134. package/dist/cli-bundle/focused-chunks/chunk-XV5RV4ZT.js +2 -0
  135. package/dist/cli-bundle/focused-chunks/{chunk-XRSCIYHR.js → chunk-YMU42COG.js} +2 -2
  136. package/dist/cli-bundle/main.js +28 -28
  137. package/dist/cli-bundle/sdk-authoring.js +1 -1
  138. package/dist/cli-bundle/sdk-contracts.js +2 -2
  139. package/dist/cli-bundle/sdk-core.js +32 -32
  140. package/dist/cli-bundle/sdk-governance.js +1 -1
  141. package/dist/cli-bundle/sdk-graph.js +1 -1
  142. package/dist/cli-bundle/sdk-merge.js +55 -55
  143. package/dist/cli-bundle/sdk-query.js +1 -1
  144. package/dist/cli-bundle/sdk-runtime.js +1 -1
  145. package/dist/cli-bundle/sdk-testing.js +1 -1
  146. package/dist/cli-bundle/sdk.js +10 -10
  147. package/dist/cli.js +1 -1
  148. package/dist/core/checkpoint/checkpoint-gc.js +1 -1
  149. package/dist/core/checkpoint/mutation-checkpoint.js +2 -2
  150. package/dist/core/config/nested-settings.js +1 -1
  151. package/dist/core/config/positional-value.js +1 -1
  152. package/dist/core/diagnostics/remediation.js +1 -1
  153. package/dist/core/extensions/activation-summary-markdown.js +2 -1
  154. package/dist/core/extensions/activation-summary.js +1 -1
  155. package/dist/core/extensions/activation-transaction.js +1 -1
  156. package/dist/core/extensions/capability-usage.js +1 -1
  157. package/dist/core/extensions/command-hook-context.js +1 -1
  158. package/dist/core/extensions/command-metadata-contract.js +1 -1
  159. package/dist/core/extensions/command-visibility-tier.js +1 -1
  160. package/dist/core/extensions/contribution-inventory.js +1 -1
  161. package/dist/core/extensions/exporter-output-contract.js +1 -1
  162. package/dist/core/extensions/extension-candidate.js +1 -1
  163. package/dist/core/extensions/extension-capability-aliases.js +1 -1
  164. package/dist/core/extensions/extension-hook-runtime.js +1 -1
  165. package/dist/core/extensions/extension-policy.js +1 -1
  166. package/dist/core/extensions/extension-registries.js +1 -1
  167. package/dist/core/extensions/extension-runtime-helpers.js +1 -1
  168. package/dist/core/extensions/extension-types.d.ts +8 -1
  169. package/dist/core/extensions/extension-types.js +1 -1
  170. package/dist/core/extensions/flag-definition-validation.js +1 -1
  171. package/dist/core/extensions/flag-value-types.js +1 -1
  172. package/dist/core/extensions/index.js +1 -1
  173. package/dist/core/extensions/item-field-types.js +1 -1
  174. package/dist/core/extensions/item-fields.js +1 -1
  175. package/dist/core/extensions/loader.js +1 -1
  176. package/dist/core/extensions/manifest-parser.js +1 -1
  177. package/dist/core/extensions/manifest-schema.js +1 -1
  178. package/dist/core/extensions/module-graph-snapshot.js +1 -1
  179. package/dist/core/extensions/preflight-ownership.js +1 -1
  180. package/dist/core/extensions/registration-contracts.js +1 -1
  181. package/dist/core/extensions/registration-validation.js +1 -1
  182. package/dist/core/extensions/registration-values.js +1 -1
  183. package/dist/core/extensions/reserved-host-flags.js +1 -1
  184. package/dist/core/extensions/runtime-registrations.js +1 -1
  185. package/dist/core/extensions/service-ownership.js +1 -1
  186. package/dist/core/extensions/version-compat.js +1 -1
  187. package/dist/core/fs/atomic-create.js +1 -1
  188. package/dist/core/fs/fs-utils.js +2 -2
  189. package/dist/core/fs/host-environment-errors.js +1 -1
  190. package/dist/core/fs/index.js +1 -1
  191. package/dist/core/fs/path-utils.js +1 -1
  192. package/dist/core/governance/content-fields.js +1 -1
  193. package/dist/core/governance/issue-codes.js +1 -1
  194. package/dist/core/governance/metadata-coverage.js +1 -1
  195. package/dist/core/history/digest.js +1 -1
  196. package/dist/core/history/drift-cache.js +3 -3
  197. package/dist/core/history/drift-scan.d.ts +4 -0
  198. package/dist/core/history/drift-scan.js +1 -1
  199. package/dist/core/history/event-classification.js +1 -1
  200. package/dist/core/history/event-index.js +8 -7
  201. package/dist/core/history/history-compact-bulk.js +1 -1
  202. package/dist/core/history/history-diff.js +1 -1
  203. package/dist/core/history/history-rewrite.js +1 -1
  204. package/dist/core/history/history-storage-stats.js +1 -1
  205. package/dist/core/history/history-stream-policy.js +1 -1
  206. package/dist/core/history/history.js +2 -2
  207. package/dist/core/history/identity.js +1 -1
  208. package/dist/core/history/index.js +1 -1
  209. package/dist/core/history/operation-contract.js +1 -1
  210. package/dist/core/history/projection.js +1 -1
  211. package/dist/core/history/read.js +1 -1
  212. package/dist/core/history/replay.js +2 -1
  213. package/dist/core/history/tombstone.js +1 -1
  214. package/dist/core/history/version-address.js +1 -1
  215. package/dist/core/history/workspace-history.js +2 -2
  216. package/dist/core/io/body-file.js +1 -1
  217. package/dist/core/io/bulk-ids-input.js +2 -1
  218. package/dist/core/item/actionability.js +1 -1
  219. package/dist/core/item/dependency-reference.js +1 -1
  220. package/dist/core/item/id.js +1 -1
  221. package/dist/core/item/index.js +1 -1
  222. package/dist/core/item/item-format-version.js +1 -1
  223. package/dist/core/item/item-format.js +6 -4
  224. package/dist/core/item/item-record.js +1 -1
  225. package/dist/core/item/item-type-definition.js +1 -1
  226. package/dist/core/item/parent-reference-policy.js +1 -1
  227. package/dist/core/item/parse.js +8 -2
  228. package/dist/core/item/plan-lifecycle.js +1 -1
  229. package/dist/core/item/priority.js +1 -1
  230. package/dist/core/item/sprint-release-format.js +1 -1
  231. package/dist/core/item/status-filter.js +1 -1
  232. package/dist/core/item/status.js +1 -1
  233. package/dist/core/item/toon-decode.js +1 -1
  234. package/dist/core/item/type-registry.js +1 -1
  235. package/dist/core/item/type-synonyms.js +1 -1
  236. package/dist/core/lock/index.js +1 -1
  237. package/dist/core/lock/lock-gc.js +1 -1
  238. package/dist/core/lock/lock.js +3 -3
  239. package/dist/core/output/mutation-projection.js +1 -1
  240. package/dist/core/output/output-control.js +1 -1
  241. package/dist/core/output/output.js +22 -10
  242. package/dist/core/output/query-summary.js +1 -1
  243. package/dist/core/output/tabular.js +3 -1
  244. package/dist/core/packages/manifest.js +1 -1
  245. package/dist/core/packages/root.js +1 -1
  246. package/dist/core/policy/workflow-policy-schema.js +1 -1
  247. package/dist/core/policy/workflow-policy-store.js +1 -1
  248. package/dist/core/policy/workflow-policy.js +1 -1
  249. package/dist/core/profile/profile-describe.js +1 -1
  250. package/dist/core/profile/profile-lint.js +1 -1
  251. package/dist/core/profile/profile-plan.js +1 -1
  252. package/dist/core/profile/profile-presets.js +25 -1
  253. package/dist/core/reproducibility/context.js +1 -1
  254. package/dist/core/schema/fields-file.js +2 -2
  255. package/dist/core/schema/item-types-file.js +2 -2
  256. package/dist/core/schema/runtime-field-filters.js +1 -1
  257. package/dist/core/schema/runtime-field-values.js +1 -1
  258. package/dist/core/schema/runtime-schema.js +2 -2
  259. package/dist/core/schema/status-defs-file.js +2 -2
  260. package/dist/core/schema/status-token.js +1 -1
  261. package/dist/core/schema/type-inference.js +1 -1
  262. package/dist/core/schema/type-presets.js +1 -1
  263. package/dist/core/schema/type-workflows.js +1 -1
  264. package/dist/core/search/background-refresh.js +2 -2
  265. package/dist/core/search/bm25.js +1 -1
  266. package/dist/core/search/cache.js +2 -2
  267. package/dist/core/search/corpus.js +1 -1
  268. package/dist/core/search/embedding-batches.js +1 -1
  269. package/dist/core/search/eval-thresholds.js +1 -1
  270. package/dist/core/search/eval.js +1 -1
  271. package/dist/core/search/http-client.js +1 -1
  272. package/dist/core/search/providers.js +1 -1
  273. package/dist/core/search/relevance.js +1 -1
  274. package/dist/core/search/semantic-defaults.js +1 -1
  275. package/dist/core/search/staleness.js +1 -1
  276. package/dist/core/search/vector-stores.js +2 -2
  277. package/dist/core/search/vectorization-metadata.js +1 -1
  278. package/dist/core/sentry/helpers.js +1 -1
  279. package/dist/core/sentry/instrument.js +1 -1
  280. package/dist/core/session/session-state.js +1 -1
  281. package/dist/core/shared/agent-session-context.js +1 -1
  282. package/dist/core/shared/author.js +5 -1
  283. package/dist/core/shared/command-line.js +1 -1
  284. package/dist/core/shared/command-types.js +1 -1
  285. package/dist/core/shared/conflict-markers.js +1 -1
  286. package/dist/core/shared/constants.js +1 -1
  287. package/dist/core/shared/errors.js +1 -1
  288. package/dist/core/shared/html-entity-decode.js +1 -1
  289. package/dist/core/shared/index.js +1 -1
  290. package/dist/core/shared/item-metadata-contract.js +1 -1
  291. package/dist/core/shared/lazy-module.js +1 -1
  292. package/dist/core/shared/levenshtein.js +1 -1
  293. package/dist/core/shared/memo.js +1 -1
  294. package/dist/core/shared/numeric-parsers.js +1 -1
  295. package/dist/core/shared/option-alias-visibility.js +1 -1
  296. package/dist/core/shared/primitives.js +1 -1
  297. package/dist/core/shared/secret-rules.js +1 -1
  298. package/dist/core/shared/serial-queue.js +1 -1
  299. package/dist/core/shared/serialization.js +1 -1
  300. package/dist/core/shared/split-comma-list.js +1 -1
  301. package/dist/core/shared/text-normalization.js +1 -1
  302. package/dist/core/shared/time.js +2 -1
  303. package/dist/core/store/index.js +1 -1
  304. package/dist/core/store/item-format-migration.js +1 -1
  305. package/dist/core/store/item-metadata-cache.js +1 -1
  306. package/dist/core/store/item-metadata-query-index.js +7 -7
  307. package/dist/core/store/item-metadata-read-work.js +1 -1
  308. package/dist/core/store/item-store.js +1 -1
  309. package/dist/core/store/paths.js +1 -1
  310. package/dist/core/store/settings-concurrency.js +1 -1
  311. package/dist/core/store/settings-read-cache.js +1 -1
  312. package/dist/core/store/settings-validator.js +1 -1
  313. package/dist/core/store/settings.d.ts +11 -2
  314. package/dist/core/store/settings.js +3 -3
  315. package/dist/core/store/tracker-preflight.js +1 -1
  316. package/dist/core/telemetry/consent.js +2 -2
  317. package/dist/core/telemetry/observability.js +1 -1
  318. package/dist/core/telemetry/policy.js +1 -1
  319. package/dist/core/telemetry/read-sampling.js +2 -2
  320. package/dist/core/telemetry/runtime.js +9 -5
  321. package/dist/core/test/background-runs.js +3 -3
  322. package/dist/core/test/item-test-run-tracking.js +1 -1
  323. package/dist/core/test/run-selectors.js +1 -1
  324. package/dist/core/validate/estimate-defaults.js +1 -1
  325. package/dist/core/validate/fix-planning.js +1 -1
  326. package/dist/core/validate/linked-artifact-reference.js +1 -1
  327. package/dist/core/validate/missing-by-type.js +1 -1
  328. package/dist/core/validate/missing-link-owners.js +1 -1
  329. package/dist/core/validate/stale-file-classification.js +1 -1
  330. package/dist/mcp/http-server.js +6 -4
  331. package/dist/mcp/legacy-adapter.js +1 -1
  332. package/dist/mcp/runtime-capabilities.js +1 -1
  333. package/dist/mcp/server.js +4 -4
  334. package/dist/mcp/tool-definitions.js +1 -1
  335. package/dist/sdk/actionability.js +1 -1
  336. package/dist/sdk/agent/closed-domain-contracts.js +1 -1
  337. package/dist/sdk/agent/command-recovery.js +1 -1
  338. package/dist/sdk/agent/command-suggestions.js +1 -1
  339. package/dist/sdk/agent/create-option-policy.js +1 -1
  340. package/dist/sdk/agent/identity-config.js +1 -1
  341. package/dist/sdk/agent/item-addressing.js +1 -1
  342. package/dist/sdk/agent/refusal-closure-census.js +2 -1
  343. package/dist/sdk/agent/refusal-closure.js +1 -1
  344. package/dist/sdk/agent/refusal-corpus-contracts.js +1 -1
  345. package/dist/sdk/agent/refusal-reachability.js +3 -1
  346. package/dist/sdk/agent/subcommand-recovery.js +1 -1
  347. package/dist/sdk/agent/task-transcript-contracts.js +1 -1
  348. package/dist/sdk/agent/tracker-preflight-contracts.js +1 -1
  349. package/dist/sdk/agent-capability-contracts.js +3 -1
  350. package/dist/sdk/agent-session-context.js +1 -1
  351. package/dist/sdk/annotations.js +1 -1
  352. package/dist/sdk/author-attribution.js +1 -1
  353. package/dist/sdk/authoring.js +1 -1
  354. package/dist/sdk/cli-bootstrap.js +1 -1
  355. package/dist/sdk/cli-contracts/agent-output-contracts.js +5 -3
  356. package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -1
  357. package/dist/sdk/cli-contracts/command-aliases.js +1 -1
  358. package/dist/sdk/cli-contracts/command-exit-contracts.js +1 -1
  359. package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1
  360. package/dist/sdk/cli-contracts/commander-types.js +1 -1
  361. package/dist/sdk/cli-contracts/completeness.js +1 -1
  362. package/dist/sdk/cli-contracts/enum-contracts.js +1 -1
  363. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  364. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +2 -1
  365. package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
  366. package/dist/sdk/cli-contracts/registration-helpers.js +7 -7
  367. package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
  368. package/dist/sdk/cli-contracts/schemas/assurance-definition.js +1 -1
  369. package/dist/sdk/cli-contracts/string-lists.js +1 -1
  370. package/dist/sdk/cli-contracts/tool-option-contracts.js +1 -1
  371. package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
  372. package/dist/sdk/cli-contracts/tool-schema.js +1 -1
  373. package/dist/sdk/cli-contracts/typed-action-inputs.js +1 -1
  374. package/dist/sdk/cli-contracts.js +1 -1
  375. package/dist/sdk/cli-program.js +1 -1
  376. package/dist/sdk/command-line.js +1 -1
  377. package/dist/sdk/comments.js +1 -1
  378. package/dist/sdk/compile-cache.js +1 -1
  379. package/dist/sdk/completion/bash.js +2 -1
  380. package/dist/sdk/completion/fish.js +13 -7
  381. package/dist/sdk/completion/shared.js +1 -1
  382. package/dist/sdk/completion/zsh.js +14 -8
  383. package/dist/sdk/completion.js +1 -1
  384. package/dist/sdk/compose.js +1 -1
  385. package/dist/sdk/config.js +1 -1
  386. package/dist/sdk/context/recency.js +1 -1
  387. package/dist/sdk/context/semantic-session-attribution.js +1 -1
  388. package/dist/sdk/context/usage-egress.js +1 -1
  389. package/dist/sdk/context/usage-ledger.js +6 -3
  390. package/dist/sdk/context-intent-contracts.js +1 -1
  391. package/dist/sdk/context-intent-runtime.js +1 -1
  392. package/dist/sdk/context-packing.js +1 -1
  393. package/dist/sdk/context-relevance.js +1 -1
  394. package/dist/sdk/context-signal-store.js +2 -2
  395. package/dist/sdk/context-usage.js +1 -1
  396. package/dist/sdk/contracts.js +1 -1
  397. package/dist/sdk/core-governance.js +1 -1
  398. package/dist/sdk/core.js +1 -1
  399. package/dist/sdk/corpus-shape.js +1 -1
  400. package/dist/sdk/define.js +1 -1
  401. package/dist/sdk/dependencies.js +1 -1
  402. package/dist/sdk/dependency-flag-validation.js +1 -1
  403. package/dist/sdk/dependency-provenance.js +1 -1
  404. package/dist/sdk/docs.js +1 -1
  405. package/dist/sdk/duplicates.js +1 -1
  406. package/dist/sdk/environment/agent-environment.js +1 -1
  407. package/dist/sdk/environment/host-environment-errors.js +1 -1
  408. package/dist/sdk/environment/project-runtime-compatibility.js +2 -1
  409. package/dist/sdk/environment/source-context.js +1 -1
  410. package/dist/sdk/environment/tracker-preflight.js +1 -1
  411. package/dist/sdk/error-code-catalog.js +1 -1
  412. package/dist/sdk/error-runtime.js +1 -1
  413. package/dist/sdk/errors.js +1 -1
  414. package/dist/sdk/eval.js +1 -1
  415. package/dist/sdk/extension/author-manifest.js +1 -1
  416. package/dist/sdk/extension/bundled-catalog.js +1 -1
  417. package/dist/sdk/extension/concurrency.js +1 -1
  418. package/dist/sdk/extension/copy-scope.js +1 -1
  419. package/dist/sdk/extension/custom-field-collisions.js +1 -1
  420. package/dist/sdk/extension/describe.js +4 -2
  421. package/dist/sdk/extension/doctor.js +1 -1
  422. package/dist/sdk/extension/install-plan.js +1 -1
  423. package/dist/sdk/extension/install-receipts.js +1 -1
  424. package/dist/sdk/extension/install-runtime.js +3 -3
  425. package/dist/sdk/extension/install-snapshot.js +1 -1
  426. package/dist/sdk/extension/install-sources.js +5 -5
  427. package/dist/sdk/extension/managed-state.js +2 -2
  428. package/dist/sdk/extension/migrations.js +2 -2
  429. package/dist/sdk/extension/output-ownership.js +1 -1
  430. package/dist/sdk/extension/runtime-summary.js +1 -1
  431. package/dist/sdk/extension/scaffold.js +11 -4
  432. package/dist/sdk/extension/shared.js +1 -1
  433. package/dist/sdk/extension/source-resolution.js +1 -1
  434. package/dist/sdk/extension/static-inventory.js +1 -1
  435. package/dist/sdk/extension/update-check.js +1 -1
  436. package/dist/sdk/extension-command-context.js +1 -1
  437. package/dist/sdk/extension-contracts.js +1 -1
  438. package/dist/sdk/extension.js +1 -1
  439. package/dist/sdk/files.js +1 -1
  440. package/dist/sdk/flag-invocation-contracts.js +1 -1
  441. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  442. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
  443. package/dist/sdk/generated-error-code-catalog.js +1 -1
  444. package/dist/sdk/governance/assurance-action-contracts.js +1 -1
  445. package/dist/sdk/governance/assurance-action.js +1 -1
  446. package/dist/sdk/governance/assurance-limits.js +1 -1
  447. package/dist/sdk/governance/assurance-mutation-error.js +1 -1
  448. package/dist/sdk/governance/assurance-presets.js +1 -1
  449. package/dist/sdk/governance/assurance-runtime.js +1 -1
  450. package/dist/sdk/governance/assurance.js +4 -4
  451. package/dist/sdk/governance/boundary-fixtures.js +1 -1
  452. package/dist/sdk/governance/closure-timestamps.js +1 -1
  453. package/dist/sdk/governance/coverage-assurance.js +1 -1
  454. package/dist/sdk/governance/defect-recurrence-coverage.js +1 -1
  455. package/dist/sdk/governance/defect-recurrence-graph.js +1 -1
  456. package/dist/sdk/governance/defect-recurrence-signals.js +1 -1
  457. package/dist/sdk/governance/defect-recurrence.js +1 -1
  458. package/dist/sdk/governance/extension-host-version.js +1 -1
  459. package/dist/sdk/governance/gc.js +1 -1
  460. package/dist/sdk/governance/health-merge-evidence.js +1 -1
  461. package/dist/sdk/governance/health.js +2 -1
  462. package/dist/sdk/governance/hierarchy-validation.js +1 -1
  463. package/dist/sdk/governance/linked-file-report.js +1 -1
  464. package/dist/sdk/governance/merge-receipt-history.js +1 -1
  465. package/dist/sdk/governance/provenance-health.js +4 -1
  466. package/dist/sdk/governance/reindex.js +5 -4
  467. package/dist/sdk/governance/stale-work.js +1 -1
  468. package/dist/sdk/governance/status-role-diagnostics.js +1 -1
  469. package/dist/sdk/governance/storage-integrity.js +1 -1
  470. package/dist/sdk/governance/tracked-runtime-cache.js +1 -1
  471. package/dist/sdk/governance/upgrade.js +2 -2
  472. package/dist/sdk/governance/validate-history-drift.js +1 -1
  473. package/dist/sdk/governance/validate-item-reader.js +1 -1
  474. package/dist/sdk/governance/validate-normalization.js +1 -1
  475. package/dist/sdk/governance/validate.js +1 -1
  476. package/dist/sdk/governance/workflow-completeness.js +1 -1
  477. package/dist/sdk/governance/workflow-policy.js +3 -3
  478. package/dist/sdk/governance/workspace-position.js +2 -1
  479. package/dist/sdk/governance.js +1 -1
  480. package/dist/sdk/graph/adapter.js +1 -1
  481. package/dist/sdk/graph/analytics.js +1 -1
  482. package/dist/sdk/graph/assembly.js +1 -1
  483. package/dist/sdk/graph/cache.js +1 -1
  484. package/dist/sdk/graph/centrality.js +1 -1
  485. package/dist/sdk/graph/conformance.js +1 -1
  486. package/dist/sdk/graph/deadline-scheduling.js +1 -1
  487. package/dist/sdk/graph/durable-cache.js +1 -1
  488. package/dist/sdk/graph/governance-contracts.js +1 -1
  489. package/dist/sdk/graph/governance.js +1 -1
  490. package/dist/sdk/graph/hierarchy-integrity.js +1 -1
  491. package/dist/sdk/graph/index.js +1 -1
  492. package/dist/sdk/graph/lifecycle-coverage.js +1 -1
  493. package/dist/sdk/graph/mutation-advisory.js +1 -1
  494. package/dist/sdk/graph/query-contracts.js +1 -1
  495. package/dist/sdk/graph/remediation.js +1 -1
  496. package/dist/sdk/graph/run.js +1 -1
  497. package/dist/sdk/graph/scheduling.js +1 -1
  498. package/dist/sdk/graph/traversal.js +1 -1
  499. package/dist/sdk/graph/workspace-relationship-kind-registry.js +1 -1
  500. package/dist/sdk/graph.js +1 -1
  501. package/dist/sdk/guide-topics.js +1 -1
  502. package/dist/sdk/guide.js +8 -1
  503. package/dist/sdk/history/attestation-command.js +1 -1
  504. package/dist/sdk/history/attestation-contract.js +1 -1
  505. package/dist/sdk/history/attestation-scan.js +1 -1
  506. package/dist/sdk/history/attestation.js +1 -1
  507. package/dist/sdk/history/maintenance.js +1 -1
  508. package/dist/sdk/history/salvage.js +3 -2
  509. package/dist/sdk/history/subject.js +1 -1
  510. package/dist/sdk/history-analytics.js +1 -1
  511. package/dist/sdk/history-compact.js +1 -1
  512. package/dist/sdk/history-mcp.js +1 -1
  513. package/dist/sdk/history-provenance.js +1 -1
  514. package/dist/sdk/history-read.js +1 -1
  515. package/dist/sdk/history-redact.js +1 -1
  516. package/dist/sdk/history-repair.js +1 -1
  517. package/dist/sdk/improvement-ledger-validation.js +1 -1
  518. package/dist/sdk/improvement-ledger.js +2 -2
  519. package/dist/sdk/index.js +1 -1
  520. package/dist/sdk/init-agent-guidance.js +16 -2
  521. package/dist/sdk/init.js +16 -2
  522. package/dist/sdk/invocation-author.js +1 -1
  523. package/dist/sdk/item-children.js +1 -1
  524. package/dist/sdk/item-metadata-index.js +1 -1
  525. package/dist/sdk/item-schedule.js +1 -1
  526. package/dist/sdk/item-transaction.js +1 -1
  527. package/dist/sdk/learnings.js +1 -1
  528. package/dist/sdk/lifecycle/append.js +4 -2
  529. package/dist/sdk/lifecycle/claim.js +1 -1
  530. package/dist/sdk/lifecycle/close-many.js +1 -1
  531. package/dist/sdk/lifecycle/close.js +1 -1
  532. package/dist/sdk/lifecycle/copy.js +1 -1
  533. package/dist/sdk/lifecycle/create.js +1 -1
  534. package/dist/sdk/lifecycle/delete.js +1 -1
  535. package/dist/sdk/lifecycle/event-validation-messages.js +1 -1
  536. package/dist/sdk/lifecycle/focus.js +1 -1
  537. package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +1 -1
  538. package/dist/sdk/lifecycle/legacy-none-tokens.js +1 -1
  539. package/dist/sdk/lifecycle/lifecycle-transitions.js +1 -1
  540. package/dist/sdk/lifecycle/mcp-actions.js +1 -1
  541. package/dist/sdk/lifecycle/metadata-normalizers.js +1 -1
  542. package/dist/sdk/lifecycle/mutation-command-options.js +1 -1
  543. package/dist/sdk/lifecycle/plan-mutation-receipt.js +1 -1
  544. package/dist/sdk/lifecycle/plan.js +1 -1
  545. package/dist/sdk/lifecycle/recurrence-parsers.js +1 -1
  546. package/dist/sdk/lifecycle/reopen.js +1 -1
  547. package/dist/sdk/lifecycle/repeatable-metadata-parsers.js +2 -1
  548. package/dist/sdk/lifecycle/restore.js +1 -1
  549. package/dist/sdk/lifecycle/shared-unset-fields.js +1 -1
  550. package/dist/sdk/lifecycle/task-composition.js +1 -1
  551. package/dist/sdk/lifecycle/update-many.js +1 -1
  552. package/dist/sdk/lifecycle/update.js +2 -1
  553. package/dist/sdk/lifecycle-completion.js +1 -1
  554. package/dist/sdk/lifecycle-policy.js +1 -1
  555. package/dist/sdk/linked-artifacts.js +2 -1
  556. package/dist/sdk/mcp/apps.js +1 -1
  557. package/dist/sdk/mcp/authorization.js +1 -1
  558. package/dist/sdk/mcp/discovery.js +1 -1
  559. package/dist/sdk/mcp/interactions.js +1 -1
  560. package/dist/sdk/mcp/protocol.js +1 -1
  561. package/dist/sdk/mcp/skills.js +3 -1
  562. package/dist/sdk/mcp/subscriptions.js +1 -1
  563. package/dist/sdk/mcp/tasks.js +2 -2
  564. package/dist/sdk/mcp/transport.js +1 -1
  565. package/dist/sdk/merge/abandoned-receipts.js +1 -1
  566. package/dist/sdk/merge/driver.js +1 -1
  567. package/dist/sdk/merge/index.js +1 -1
  568. package/dist/sdk/merge/install.js +4 -2
  569. package/dist/sdk/merge/receipt-file-boundary.js +1 -1
  570. package/dist/sdk/merge/receipt-operation.js +1 -1
  571. package/dist/sdk/merge/receipt-schema.js +1 -1
  572. package/dist/sdk/merge/receipts.js +4 -4
  573. package/dist/sdk/merge/reconcile.js +1 -1
  574. package/dist/sdk/merge/three-way.js +3 -2
  575. package/dist/sdk/merge/worktree-config.js +1 -1
  576. package/dist/sdk/merge.js +1 -1
  577. package/dist/sdk/mutation-events.js +1 -1
  578. package/dist/sdk/mutation-guard.js +1 -1
  579. package/dist/sdk/notes.js +1 -1
  580. package/dist/sdk/output-contracts.js +1 -1
  581. package/dist/sdk/output-projection.js +1 -1
  582. package/dist/sdk/output-token-accounting.js +1 -1
  583. package/dist/sdk/output.js +2 -1
  584. package/dist/sdk/ownership-source.js +1 -1
  585. package/dist/sdk/package-import-adapters.js +1 -1
  586. package/dist/sdk/package-migrations.js +1 -1
  587. package/dist/sdk/package-runtime-options.js +1 -1
  588. package/dist/sdk/pagination.js +1 -1
  589. package/dist/sdk/profile.js +5 -1
  590. package/dist/sdk/provenance.js +1 -1
  591. package/dist/sdk/public-surface.json +1 -1
  592. package/dist/sdk/query/activity.js +1 -1
  593. package/dist/sdk/query/aggregate.js +1 -1
  594. package/dist/sdk/query/calendar.js +4 -1
  595. package/dist/sdk/query/complete-list.js +1 -1
  596. package/dist/sdk/query/context.js +2 -1
  597. package/dist/sdk/query/duplicate-candidates.js +1 -1
  598. package/dist/sdk/query/get.d.ts +14 -2
  599. package/dist/sdk/query/get.js +1 -1
  600. package/dist/sdk/query/history.js +1 -1
  601. package/dist/sdk/query/item-filter-options.js +1 -1
  602. package/dist/sdk/query/light-metadata.js +1 -1
  603. package/dist/sdk/query/list-filter-shared.js +1 -1
  604. package/dist/sdk/query/list.js +1 -1
  605. package/dist/sdk/query/multi-value-filters.js +1 -1
  606. package/dist/sdk/query/next-ready-budget.js +1 -1
  607. package/dist/sdk/query/next.js +2 -1
  608. package/dist/sdk/query/parsers.js +1 -1
  609. package/dist/sdk/query/projection-contracts.js +1 -1
  610. package/dist/sdk/query/search/corpus.js +2 -1
  611. package/dist/sdk/query/search/filters.js +1 -1
  612. package/dist/sdk/query/search/input.js +1 -1
  613. package/dist/sdk/query/search/lexical.js +1 -1
  614. package/dist/sdk/query/search/response.js +1 -1
  615. package/dist/sdk/query/search/semantic.js +3 -2
  616. package/dist/sdk/query/search/types.js +1 -1
  617. package/dist/sdk/query/search-contracts.js +1 -1
  618. package/dist/sdk/query/search-pagination.d.ts +1 -1
  619. package/dist/sdk/query/search-pagination.js +1 -1
  620. package/dist/sdk/query/search-rendering.js +1 -1
  621. package/dist/sdk/query/search.js +1 -1
  622. package/dist/sdk/query/workspace-contracts.js +1 -1
  623. package/dist/sdk/query.js +1 -1
  624. package/dist/sdk/read-output/continuation.js +1 -1
  625. package/dist/sdk/read-output/options.js +1 -1
  626. package/dist/sdk/read-output/provenance.js +1 -1
  627. package/dist/sdk/read-output-budget.js +1 -1
  628. package/dist/sdk/read-output-contracts.js +1 -1
  629. package/dist/sdk/read-output-rows.js +1 -1
  630. package/dist/sdk/read-output-session.js +1 -1
  631. package/dist/sdk/relationship-analytics.js +1 -1
  632. package/dist/sdk/relationship-context.js +1 -1
  633. package/dist/sdk/relationship-history.js +7 -4
  634. package/dist/sdk/relationship-kinds/contract.js +1 -1
  635. package/dist/sdk/relationship-migration.js +1 -1
  636. package/dist/sdk/relationships.js +1 -1
  637. package/dist/sdk/reproducibility/process.js +1 -1
  638. package/dist/sdk/runtime/actions.js +1 -1
  639. package/dist/sdk/runtime/context.js +1 -1
  640. package/dist/sdk/runtime/schema-preview.js +1 -1
  641. package/dist/sdk/runtime/schema.js +1 -1
  642. package/dist/sdk/runtime-action-aliases.js +1 -1
  643. package/dist/sdk/runtime-extended-actions.js +1 -1
  644. package/dist/sdk/runtime-input.js +1 -1
  645. package/dist/sdk/runtime-primitives.js +1 -1
  646. package/dist/sdk/runtime-public-contracts.js +1 -1
  647. package/dist/sdk/runtime-stats-options.js +1 -1
  648. package/dist/sdk/runtime.js +1 -1
  649. package/dist/sdk/scheduling-shortcuts.js +1 -1
  650. package/dist/sdk/schema-migration.js +4 -3
  651. package/dist/sdk/schema.js +7 -1
  652. package/dist/sdk/search-refresh-worker.js +1 -1
  653. package/dist/sdk/similarity-scoring.js +1 -1
  654. package/dist/sdk/similarity.js +1 -1
  655. package/dist/sdk/start-task-status.js +1 -1
  656. package/dist/sdk/stats.js +1 -1
  657. package/dist/sdk/structured-mutations.js +1 -1
  658. package/dist/sdk/telemetry-flush.js +1 -1
  659. package/dist/sdk/telemetry.js +4 -3
  660. package/dist/sdk/templates.js +26 -2
  661. package/dist/sdk/test/batch.js +2 -2
  662. package/dist/sdk/test/entry.js +1 -1
  663. package/dist/sdk/test/execution.js +6 -5
  664. package/dist/sdk/test/json-path.js +1 -1
  665. package/dist/sdk/test/linked-command-detection.js +1 -1
  666. package/dist/sdk/test/measurements.js +1 -1
  667. package/dist/sdk/test/parsers.js +1 -1
  668. package/dist/sdk/test/runs.js +1 -1
  669. package/dist/sdk/test/trust.js +2 -2
  670. package/dist/sdk/test/workspace-snapshot.js +1 -1
  671. package/dist/sdk/testing.js +7 -4
  672. package/dist/sdk/traceability/runtime-files-lookup.js +1 -1
  673. package/dist/sdk/traceability/source-traceability.js +2 -1
  674. package/dist/sdk/tracker-root-discovery.js +1 -1
  675. package/dist/sdk/workspace-contracts-cache.js +1 -1
  676. package/dist/sdk/workspace-contracts.js +1 -1
  677. package/dist/sdk/workspace-memory.js +2 -2
  678. package/dist/sdk/workspace-recipe.js +1 -1
  679. package/dist/sdk/workspace-snapshot.js +5 -4
  680. package/dist/sdk/workspace-transaction-gc.js +1 -1
  681. package/dist/sdk/workspace-transaction.js +2 -2
  682. package/dist/sdk/workspace.js +3 -2
  683. package/dist/types/index.js +1 -1
  684. package/dist/types.js +1 -1
  685. package/docs/AGENT_EVIDENCE_CONSISTENCY.md +88 -0
  686. package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +25 -0
  687. package/docs/GET_READ_EVIDENCE.md +68 -0
  688. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +23 -0
  689. package/docs/README.md +2 -0
  690. package/docs/SDK_AUDITED_MUTATIONS.md +35 -0
  691. package/docs/TESTING.md +8 -0
  692. package/docs/ecosystem-review-2026-09-28.json +2864 -3157
  693. package/marketplace.json +2 -2
  694. package/package.json +1 -1
  695. package/packages/pm-beads/package.json +1 -1
  696. package/packages/pm-calendar/package.json +1 -1
  697. package/packages/pm-command-kit/package.json +1 -1
  698. package/packages/pm-digital-twin/package.json +1 -1
  699. package/packages/pm-governance-audit/package.json +1 -1
  700. package/packages/pm-guide-shell/package.json +1 -1
  701. package/packages/pm-kanban/package.json +1 -1
  702. package/packages/pm-lifecycle-hooks/package.json +1 -1
  703. package/packages/pm-linked-test-adapters/package.json +1 -1
  704. package/packages/pm-search-advanced/package.json +1 -1
  705. package/packages/pm-templates/package.json +1 -1
  706. package/packages/pm-todos/package.json +1 -1
  707. package/packages/pm-vcs/extensions/vcs/index.ts +4 -2
  708. package/packages/pm-vcs/package.json +1 -1
  709. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  710. package/plugins/pm-claude/package.json +2 -2
  711. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  712. package/plugins/pm-codex/package.json +2 -2
  713. package/plugins/pm-codex/plugin.json +1 -1
  714. package/scripts/finalize-build.mjs +3 -2
  715. package/dist/cli-bundle/chunks/chunk-3AF2R3Y6.js +0 -6
  716. package/dist/cli-bundle/chunks/chunk-6ST3SCQ6.js +0 -2
  717. package/dist/cli-bundle/chunks/chunk-6Z4IV2MC.js +0 -8
  718. package/dist/cli-bundle/chunks/chunk-DEZPZOQ7.js +0 -2
  719. package/dist/cli-bundle/chunks/chunk-FW5LJXQY.js +0 -31
  720. package/dist/cli-bundle/chunks/chunk-H2DZW6I6.js +0 -3
  721. package/dist/cli-bundle/chunks/chunk-H7CXQBGQ.js +0 -2
  722. package/dist/cli-bundle/chunks/chunk-KP7NBQK3.js +0 -80
  723. package/dist/cli-bundle/chunks/chunk-MKXBCBAN.js +0 -20
  724. package/dist/cli-bundle/chunks/chunk-QPKQKSQU.js +0 -238
  725. package/dist/cli-bundle/chunks/chunk-SGFQQXFD.js +0 -2
  726. package/dist/cli-bundle/chunks/chunk-YCBGZF3T.js +0 -2
  727. package/dist/cli-bundle/chunks/chunk-YDWKGUQU.js +0 -3
  728. package/dist/cli-bundle/chunks/register-mutation-5PT3NW3A.js +0 -20
  729. package/dist/cli-bundle/chunks/register-operations-QDDQOAAV.js +0 -2
  730. package/dist/cli-bundle/chunks/register-setup-BBX67YMA.js +0 -2
  731. package/dist/cli-bundle/focused-chunks/chunk-4FFPGNCJ.js +0 -6
  732. package/dist/cli-bundle/focused-chunks/chunk-73DA7ISY.js +0 -75
  733. package/dist/cli-bundle/focused-chunks/chunk-E754JDLY.js +0 -2
  734. package/dist/cli-bundle/focused-chunks/chunk-FKK2HI3S.js +0 -2
  735. package/dist/cli-bundle/focused-chunks/chunk-GMYUNHST.js +0 -3
  736. package/dist/cli-bundle/focused-chunks/chunk-HIA2ZF64.js +0 -12
  737. package/dist/cli-bundle/focused-chunks/chunk-UTRSM3ZK.js +0 -8
  738. package/dist/cli-bundle/focused-chunks/chunk-VVWYI2X7.js +0 -2
  739. package/dist/cli-bundle/focused-chunks/chunk-WAJNX4RN.js +0 -20
  740. package/dist/cli-bundle/focused-chunks/chunk-WCY6HRZO.js +0 -30
  741. package/dist/cli-bundle/focused-chunks/chunk-YC32ZSLS.js +0 -165
  742. package/dist/cli-bundle/focused-chunks/chunk-ZIXFMIUL.js +0 -3
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6a5310f6-3add-5108-b39f-61607918dc9f")}catch(e2){}})();import{AsyncLocalStorage}from"node:async_hooks";import{createHash,timingSafeEqual}from"node:crypto";import{isMcpRecord}from"./protocol.js";class PmMcpAuthorizationError extends Error{httpStatus;challenge;constructor(message,httpStatus,challenge){super(message);this.name="PmMcpAuthorizationError";this.httpStatus=httpStatus;this.challenge=challenge}}const TRACE_PARENT_PATTERN=/^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/u;const TRACE_STATE_SIMPLE_KEY_PATTERN=/^[a-z][a-z0-9_*/-]{0,255}$/u;const TRACE_STATE_TENANT_KEY_PATTERN=/^(?:[a-z0-9][a-z0-9_*/-]{0,240})@[a-z][a-z0-9_*/-]{0,13}$/u;const TRACE_STATE_VALUE_PATTERN=/^[\x20-\x2B\x2D-\x3C\x3E-\x7E]{0,255}[\x21-\x2B\x2D-\x3C\x3E-\x7E]$/u;const SCOPE_PATTERN=/^[\x21\x23-\x5B\x5D-\x7E]+$/u;const BAGGAGE_KEY_PATTERN=/^[A-Za-z0-9!#$%&'*+.^_`|~-]+$/u;const BAGGAGE_VALUE_PATTERN=/^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]*$/u;const INVALID_PERCENT_ENCODING_PATTERN=/%(?![0-9A-Fa-f]{2})/u;const MAX_TRACE_STATE_BYTES=512;const MAX_TRACE_STATE_MEMBERS=32;const MAX_BAGGAGE_MEMBERS=180;const MAX_BAGGAGE_BYTES=8192;const MAX_BEARER_TOKEN_BYTES=8192;const MCP_TRACE_CONTEXT_STORAGE=new AsyncLocalStorage;function requireAbsoluteAuthorizationUrl(value,field,allowLocalHttp=false){if(new RegExp("\\p{Cc}","u").test(value)){throw new PmMcpAuthorizationError(`Invalid ${field}`,401)}let parsed;try{parsed=new URL(value)}catch{throw new PmMcpAuthorizationError(`Invalid ${field}`,401)}const local=parsed.hostname==="127.0.0.1"||parsed.hostname==="localhost";if(parsed.hash.length>0||parsed.protocol!=="https:"&&!(allowLocalHttp&&local&&parsed.protocol==="http:")){throw new PmMcpAuthorizationError(`Invalid ${field}`,401)}return parsed}function readHeader(headers,name){const expected=name.toLowerCase();for(const[candidate,value]of Object.entries(headers)){if(candidate.toLowerCase()!==expected||value===void 0)continue;return typeof value==="string"?value:value.join(", ")}return void 0}function buildMcpProtectedResourceMetadata(input){const resource=requireAbsoluteAuthorizationUrl(input.resource,"protected resource URI",true).href.replace(/\/$/u,"");if(input.authorizationServers.length===0){throw new PmMcpAuthorizationError("Protected resource metadata requires an authorization server",401)}const authorizationServers=input.authorizationServers.map(issuer=>requireAbsoluteAuthorizationUrl(issuer,"authorization server issuer").href.replace(/\/$/u,""));const scopes=[...new Set(input.scopes??[])];if(scopes.some(scope=>!SCOPE_PATTERN.test(scope))){throw new PmMcpAuthorizationError("Invalid authorization scope",401)}return{resource,authorization_servers:authorizationServers,...scopes.length>0?{scopes_supported:scopes.sort()}:{}}}function buildMcpAuthorizationDiscoveryUrls(issuer){const parsed=requireAbsoluteAuthorizationUrl(issuer,"authorization server issuer");const suffix=parsed.pathname.replace(/^\/+|\/+$/gu,"");const origin=parsed.origin;return suffix?[`${origin}/.well-known/oauth-authorization-server/${suffix}`,`${origin}/.well-known/openid-configuration/${suffix}`,`${origin}/${suffix}/.well-known/openid-configuration`]:[`${origin}/.well-known/oauth-authorization-server`,`${origin}/.well-known/openid-configuration`]}function validateMcpAuthorizationServerMetadata(value,expectedIssuer){if(!isMcpRecord(value)||typeof value.issuer!=="string"){throw new PmMcpAuthorizationError("Invalid authorization server metadata",401)}const expected=requireAbsoluteAuthorizationUrl(expectedIssuer,"expected issuer").href.replace(/\/$/u,"");const observed=requireAbsoluteAuthorizationUrl(value.issuer,"metadata issuer").href.replace(/\/$/u,"");if(observed!==expected){throw new PmMcpAuthorizationError("Authorization server issuer mismatch",401)}if(!Array.isArray(value.code_challenge_methods_supported)||!value.code_challenge_methods_supported.includes("S256")){throw new PmMcpAuthorizationError("Authorization server does not support required S256 PKCE",401)}const requiredUrl=field=>{const candidate=value[field];if(typeof candidate!=="string"){throw new PmMcpAuthorizationError(`Authorization server metadata requires ${field}`,401)}return requireAbsoluteAuthorizationUrl(candidate,field).href};const optionalUrl=field=>{const candidate=value[field];return typeof candidate==="string"?requireAbsoluteAuthorizationUrl(candidate,field).href:void 0};const authorizationEndpoint=requiredUrl("authorization_endpoint");const tokenEndpoint=requiredUrl("token_endpoint");const registrationEndpoint=optionalUrl("registration_endpoint");return{issuer:expected,authorization_endpoint:authorizationEndpoint,token_endpoint:tokenEndpoint,code_challenge_methods_supported:[...new Set(value.code_challenge_methods_supported.filter(entry=>typeof entry==="string"))],...value.client_id_metadata_document_supported===true?{client_id_metadata_document_supported:true}:{},...registrationEndpoint?{registration_endpoint:registrationEndpoint}:{}}}function selectMcpClientRegistrationMode(input){if(input.hasPreRegisteredClient)return"pre_registered";if(input.metadata.client_id_metadata_document_supported)return"client_id_metadata_document";if(input.metadata.registration_endpoint)return"dynamic";return"user_supplied"}function validateMcpAuthorizationResponseIssuer(input){if(input.responseIssuer===void 0){if(input.issuerParameterSupported){throw new PmMcpAuthorizationError("Authorization response omitted the advertised issuer",401)}return}if(input.responseIssuer!==input.expectedIssuer){throw new PmMcpAuthorizationError("Authorization response issuer mismatch",401)}}function validateMcpClientMetadataDocument(value,documentUrl){const expected=requireAbsoluteAuthorizationUrl(documentUrl,"client metadata document URL");if(expected.pathname==="/"||!isMcpRecord(value)||value.client_id!==expected.href||typeof value.client_name!=="string"||value.client_name.trim().length===0||!Array.isArray(value.redirect_uris)||value.redirect_uris.length===0){throw new PmMcpAuthorizationError("Invalid Client ID Metadata Document",401)}for(const redirect of value.redirect_uris){if(typeof redirect!=="string"){throw new PmMcpAuthorizationError("Invalid client redirect URI",401)}requireAbsoluteAuthorizationUrl(redirect,"client redirect URI",true)}return structuredClone(value)}function buildMcpDynamicRegistrationMetadata(input){if(input.redirectUris.length===0||input.clientName.trim().length===0){throw new PmMcpAuthorizationError("Invalid dynamic client registration metadata",401)}const redirectUris=input.redirectUris.map(redirect=>requireAbsoluteAuthorizationUrl(redirect,"redirect URI",true).href);return{application_type:input.applicationType,client_name:input.clientName.trim().slice(0,128),redirect_uris:redirectUris,grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"}}class PmMcpIssuerCredentialStore{#credentials=new Map;set(issuer,credential){const key=requireAbsoluteAuthorizationUrl(issuer,"credential issuer").href;this.#credentials.set(key,structuredClone(credential))}get(issuer){const key=requireAbsoluteAuthorizationUrl(issuer,"credential issuer").href;const credential=this.#credentials.get(key);return credential?structuredClone(credential):void 0}delete(issuer){const key=requireAbsoluteAuthorizationUrl(issuer,"credential issuer").href;return this.#credentials.delete(key)}}function validateMcpTraceFields(meta){const traceparent=meta.traceparent;const tracestate=meta.tracestate;if(traceparent!==void 0){const match=typeof traceparent==="string"?TRACE_PARENT_PATTERN.exec(traceparent):null;if(!match){throw new PmMcpAuthorizationError("Invalid MCP traceparent",403)}const traceId=match[1];const parentId=match[2];if(/^0+$/u.test(traceId)||/^0+$/u.test(parentId)){throw new PmMcpAuthorizationError("Invalid MCP traceparent",403)}}if(tracestate!==void 0&&(typeof tracestate!=="string"||!isValidMcpTraceState(tracestate))){throw new PmMcpAuthorizationError("Invalid MCP tracestate",403)}return{...typeof traceparent==="string"?{traceparent}:{},...typeof tracestate==="string"?{tracestate}:{}}}function trimOptionalWhitespace(value){return value.replace(/^[ \t]*|[ \t]*$/gu,"")}function isValidMcpTraceStateKey(key){return TRACE_STATE_SIMPLE_KEY_PATTERN.test(key)||TRACE_STATE_TENANT_KEY_PATTERN.test(key)}function isValidMcpTraceState(value){if(Buffer.byteLength(value,"utf8")>MAX_TRACE_STATE_BYTES)return false;const members=value.split(",");if(members.length>MAX_TRACE_STATE_MEMBERS)return false;const keys=new Set;for(const source of members){const member=trimOptionalWhitespace(source);if(member.length===0)continue;const separator=member.indexOf("=");const key=separator>0?member.slice(0,separator):"";const memberValue=separator>0?member.slice(separator+1):"";if(!isValidMcpTraceStateKey(key)||!TRACE_STATE_VALUE_PATTERN.test(memberValue)||keys.has(key)){return false}keys.add(key)}return true}function isValidMcpBaggageValue(value){return BAGGAGE_VALUE_PATTERN.test(value)&&!INVALID_PERCENT_ENCODING_PATTERN.test(value)}function isValidMcpBaggageProperty(source){const property=trimOptionalWhitespace(source);const separator=property.indexOf("=");const key=trimOptionalWhitespace(separator>=0?property.slice(0,separator):property);const value=separator>=0?trimOptionalWhitespace(property.slice(separator+1)):void 0;return BAGGAGE_KEY_PATTERN.test(key)&&(value===void 0||isValidMcpBaggageValue(value))}function parseMcpBaggageMember(source){const serialized=trimOptionalWhitespace(source);const segments=serialized.split(";");const pair=segments[0];const properties=segments.slice(1);const separator=pair.indexOf("=");const key=trimOptionalWhitespace(separator>0?pair.slice(0,separator):"");const value=separator>0?trimOptionalWhitespace(pair.slice(separator+1)):"";if(!BAGGAGE_KEY_PATTERN.test(key)||!isValidMcpBaggageValue(value)||!properties.every(isValidMcpBaggageProperty)){return void 0}return{key,serialized}}function filterMcpBaggage(baggage,allowlistEntries){if(baggage===void 0)return void 0;if(typeof baggage!=="string"||Buffer.byteLength(baggage,"utf8")>MAX_BAGGAGE_BYTES){throw new PmMcpAuthorizationError("Invalid MCP baggage",403)}const allowlist=new Set(allowlistEntries);const sources=baggage.split(",");if(sources.length>MAX_BAGGAGE_MEMBERS){throw new PmMcpAuthorizationError("Invalid MCP baggage",403)}const entries=[];for(const source of sources){const entry=parseMcpBaggageMember(source);if(!entry){throw new PmMcpAuthorizationError("Invalid MCP baggage",403)}if(allowlist.has(entry.key))entries.push(entry.serialized)}return entries.length>0?entries.join(","):void 0}function extractMcpTraceContext(params,options={}){const meta=isMcpRecord(params)&&isMcpRecord(params._meta)?params._meta:{};const allowedBaggage=filterMcpBaggage(meta.baggage,options.baggageAllowlist??[]);return{...validateMcpTraceFields(meta),...allowedBaggage?{baggage:allowedBaggage}:{}}}function runWithMcpTraceContext(context,callback){return MCP_TRACE_CONTEXT_STORAGE.run(structuredClone(context),callback)}function getActiveMcpTraceContext(){const context=MCP_TRACE_CONTEXT_STORAGE.getStore();return context?{...context}:void 0}async function authorizeMcpHttpRequest(input){const resourceMetadataUrl=requireAbsoluteAuthorizationUrl(input.policy.resourceMetadataUrl,"protected resource metadata URL",true).href;const requiredScopes=[...new Set(input.policy.requiredScopes??[])];if(requiredScopes.some(scope=>!SCOPE_PATTERN.test(scope))){throw new PmMcpAuthorizationError("Invalid authorization scope",401)}const challenge=`Bearer resource_metadata="${resourceMetadataUrl}"`;const parsedUrl=new URL(input.requestUrl,input.policy.resource);if(parsedUrl.searchParams.has("access_token")){throw new PmMcpAuthorizationError("Access tokens must not appear in URI query parameters",401,challenge)}const authorization=readHeader(input.headers,"authorization");const match=authorization?.match(/^Bearer ([^\s]+)$/iu);if(!match){throw new PmMcpAuthorizationError("Missing or malformed bearer token",401,challenge)}const token=match[1];if(Buffer.byteLength(token,"utf8")>MAX_BEARER_TOKEN_BYTES){throw new PmMcpAuthorizationError("Missing or malformed bearer token",401,challenge)}let claims;try{claims=await input.policy.verifyAccessToken(token)}catch{throw new PmMcpAuthorizationError("Invalid bearer token",401,challenge)}const audiences=Array.isArray(claims.audience)?claims.audience:[claims.audience];if(claims.issuer!==input.policy.issuer||!audiences.includes(input.policy.resource)){throw new PmMcpAuthorizationError("Bearer token issuer or audience mismatch",401,challenge)}const missingScopes=requiredScopes.filter(scope=>!claims.scopes.includes(scope));if(missingScopes.length>0){throw new PmMcpAuthorizationError("Bearer token has insufficient scope",403,`${challenge}, scope="${missingScopes.join(" ")}"`)}return{...claims,audience:[...audiences],scopes:[...claims.scopes]}}function createMcpStaticBearerVerifier(input){const expected=createHash("sha256").update(input.token).digest();return token=>{const observed=createHash("sha256").update(token).digest();if(!timingSafeEqual(expected,observed)){throw new PmMcpAuthorizationError("Invalid bearer token",401)}return structuredClone(input.claims)}}export{PmMcpAuthorizationError,PmMcpIssuerCredentialStore,authorizeMcpHttpRequest,buildMcpAuthorizationDiscoveryUrls,buildMcpDynamicRegistrationMetadata,buildMcpProtectedResourceMetadata,createMcpStaticBearerVerifier,extractMcpTraceContext,getActiveMcpTraceContext,runWithMcpTraceContext,selectMcpClientRegistrationMode,validateMcpAuthorizationResponseIssuer,validateMcpAuthorizationServerMetadata,validateMcpClientMetadataDocument};
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]="a7c30d99-a0e4-552e-be61-0c54a455e211")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{createHash,timingSafeEqual}from"node:crypto";import{isMcpRecord}from"./protocol.js";class PmMcpAuthorizationError extends Error{httpStatus;challenge;constructor(message,httpStatus,challenge){super(message),this.name="PmMcpAuthorizationError",this.httpStatus=httpStatus,this.challenge=challenge}}const TRACE_PARENT_PATTERN=/^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/u,TRACE_STATE_SIMPLE_KEY_PATTERN=/^[a-z][a-z0-9_*/-]{0,255}$/u,TRACE_STATE_TENANT_KEY_PATTERN=/^(?:[a-z0-9][a-z0-9_*/-]{0,240})@[a-z][a-z0-9_*/-]{0,13}$/u,TRACE_STATE_VALUE_PATTERN=/^[\x20-\x2B\x2D-\x3C\x3E-\x7E]{0,255}[\x21-\x2B\x2D-\x3C\x3E-\x7E]$/u,SCOPE_PATTERN=/^[\x21\x23-\x5B\x5D-\x7E]+$/u,BAGGAGE_KEY_PATTERN=/^[A-Za-z0-9!#$%&'*+.^_`|~-]+$/u,BAGGAGE_VALUE_PATTERN=/^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]*$/u,INVALID_PERCENT_ENCODING_PATTERN=/%(?![0-9A-Fa-f]{2})/u,MAX_TRACE_STATE_BYTES=512,MAX_TRACE_STATE_MEMBERS=32,MAX_BAGGAGE_MEMBERS=180,MAX_BAGGAGE_BYTES=8192,MAX_BEARER_TOKEN_BYTES=8192,MCP_TRACE_CONTEXT_STORAGE=new AsyncLocalStorage;function requireAbsoluteAuthorizationUrl(value,field,allowLocalHttp=!1){if(new RegExp("\\p{Cc}","u").test(value))throw new PmMcpAuthorizationError(`Invalid ${field}`,401);let parsed;try{parsed=new URL(value)}catch{throw new PmMcpAuthorizationError(`Invalid ${field}`,401)}const local=parsed.hostname==="127.0.0.1"||parsed.hostname==="localhost";if(parsed.hash.length>0||parsed.protocol!=="https:"&&!(allowLocalHttp&&local&&parsed.protocol==="http:"))throw new PmMcpAuthorizationError(`Invalid ${field}`,401);return parsed}function readHeader(headers,name){const expected=name.toLowerCase();for(const[candidate,value]of Object.entries(headers))if(!(candidate.toLowerCase()!==expected||value===void 0))return typeof value=="string"?value:value.join(", ")}function buildMcpProtectedResourceMetadata(input){const resource=requireAbsoluteAuthorizationUrl(input.resource,"protected resource URI",!0).href.replace(/\/$/u,"");if(input.authorizationServers.length===0)throw new PmMcpAuthorizationError("Protected resource metadata requires an authorization server",401);const authorizationServers=input.authorizationServers.map(issuer=>requireAbsoluteAuthorizationUrl(issuer,"authorization server issuer").href.replace(/\/$/u,"")),scopes=[...new Set(input.scopes??[])];if(scopes.some(scope=>!SCOPE_PATTERN.test(scope)))throw new PmMcpAuthorizationError("Invalid authorization scope",401);return{resource,authorization_servers:authorizationServers,...scopes.length>0?{scopes_supported:scopes.sort()}:{}}}function buildMcpAuthorizationDiscoveryUrls(issuer){const parsed=requireAbsoluteAuthorizationUrl(issuer,"authorization server issuer"),suffix=parsed.pathname.replace(/^\/+|\/+$/gu,""),origin=parsed.origin;return suffix?[`${origin}/.well-known/oauth-authorization-server/${suffix}`,`${origin}/.well-known/openid-configuration/${suffix}`,`${origin}/${suffix}/.well-known/openid-configuration`]:[`${origin}/.well-known/oauth-authorization-server`,`${origin}/.well-known/openid-configuration`]}function validateMcpAuthorizationServerMetadata(value,expectedIssuer){if(!isMcpRecord(value)||typeof value.issuer!="string")throw new PmMcpAuthorizationError("Invalid authorization server metadata",401);const expected=requireAbsoluteAuthorizationUrl(expectedIssuer,"expected issuer").href.replace(/\/$/u,"");if(requireAbsoluteAuthorizationUrl(value.issuer,"metadata issuer").href.replace(/\/$/u,"")!==expected)throw new PmMcpAuthorizationError("Authorization server issuer mismatch",401);if(!Array.isArray(value.code_challenge_methods_supported)||!value.code_challenge_methods_supported.includes("S256"))throw new PmMcpAuthorizationError("Authorization server does not support required S256 PKCE",401);const requiredUrl=field=>{const candidate=value[field];if(typeof candidate!="string")throw new PmMcpAuthorizationError(`Authorization server metadata requires ${field}`,401);return requireAbsoluteAuthorizationUrl(candidate,field).href},optionalUrl=field=>{const candidate=value[field];return typeof candidate=="string"?requireAbsoluteAuthorizationUrl(candidate,field).href:void 0},authorizationEndpoint=requiredUrl("authorization_endpoint"),tokenEndpoint=requiredUrl("token_endpoint"),registrationEndpoint=optionalUrl("registration_endpoint");return{issuer:expected,authorization_endpoint:authorizationEndpoint,token_endpoint:tokenEndpoint,code_challenge_methods_supported:[...new Set(value.code_challenge_methods_supported.filter(entry=>typeof entry=="string"))],...value.client_id_metadata_document_supported===!0?{client_id_metadata_document_supported:!0}:{},...registrationEndpoint?{registration_endpoint:registrationEndpoint}:{}}}function selectMcpClientRegistrationMode(input){return input.hasPreRegisteredClient?"pre_registered":input.metadata.client_id_metadata_document_supported?"client_id_metadata_document":input.metadata.registration_endpoint?"dynamic":"user_supplied"}function validateMcpAuthorizationResponseIssuer(input){if(input.responseIssuer===void 0){if(input.issuerParameterSupported)throw new PmMcpAuthorizationError("Authorization response omitted the advertised issuer",401);return}if(input.responseIssuer!==input.expectedIssuer)throw new PmMcpAuthorizationError("Authorization response issuer mismatch",401)}function validateMcpClientMetadataDocument(value,documentUrl){const expected=requireAbsoluteAuthorizationUrl(documentUrl,"client metadata document URL");if(expected.pathname==="/"||!isMcpRecord(value)||value.client_id!==expected.href||typeof value.client_name!="string"||value.client_name.trim().length===0||!Array.isArray(value.redirect_uris)||value.redirect_uris.length===0)throw new PmMcpAuthorizationError("Invalid Client ID Metadata Document",401);for(const redirect of value.redirect_uris){if(typeof redirect!="string")throw new PmMcpAuthorizationError("Invalid client redirect URI",401);requireAbsoluteAuthorizationUrl(redirect,"client redirect URI",!0)}return structuredClone(value)}function buildMcpDynamicRegistrationMetadata(input){if(input.redirectUris.length===0||input.clientName.trim().length===0)throw new PmMcpAuthorizationError("Invalid dynamic client registration metadata",401);const redirectUris=input.redirectUris.map(redirect=>requireAbsoluteAuthorizationUrl(redirect,"redirect URI",!0).href);return{application_type:input.applicationType,client_name:input.clientName.trim().slice(0,128),redirect_uris:redirectUris,grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"}}class PmMcpIssuerCredentialStore{#credentials=new Map;set(issuer,credential){const key=requireAbsoluteAuthorizationUrl(issuer,"credential issuer").href;this.#credentials.set(key,structuredClone(credential))}get(issuer){const key=requireAbsoluteAuthorizationUrl(issuer,"credential issuer").href,credential=this.#credentials.get(key);return credential?structuredClone(credential):void 0}delete(issuer){const key=requireAbsoluteAuthorizationUrl(issuer,"credential issuer").href;return this.#credentials.delete(key)}}function validateMcpTraceFields(meta){const traceparent=meta.traceparent,tracestate=meta.tracestate;if(traceparent!==void 0){const match=typeof traceparent=="string"?TRACE_PARENT_PATTERN.exec(traceparent):null;if(!match)throw new PmMcpAuthorizationError("Invalid MCP traceparent",403);const traceId=match[1],parentId=match[2];if(/^0+$/u.test(traceId)||/^0+$/u.test(parentId))throw new PmMcpAuthorizationError("Invalid MCP traceparent",403)}if(tracestate!==void 0&&(typeof tracestate!="string"||!isValidMcpTraceState(tracestate)))throw new PmMcpAuthorizationError("Invalid MCP tracestate",403);return{...typeof traceparent=="string"?{traceparent}:{},...typeof tracestate=="string"?{tracestate}:{}}}function trimOptionalWhitespace(value){return value.replace(/^[ \t]*|[ \t]*$/gu,"")}function isValidMcpTraceStateKey(key){return TRACE_STATE_SIMPLE_KEY_PATTERN.test(key)||TRACE_STATE_TENANT_KEY_PATTERN.test(key)}function isValidMcpTraceState(value){if(Buffer.byteLength(value,"utf8")>MAX_TRACE_STATE_BYTES)return!1;const members=value.split(",");if(members.length>MAX_TRACE_STATE_MEMBERS)return!1;const keys=new Set;for(const source of members){const member=trimOptionalWhitespace(source);if(member.length===0)continue;const separator=member.indexOf("="),key=separator>0?member.slice(0,separator):"",memberValue=separator>0?member.slice(separator+1):"";if(!isValidMcpTraceStateKey(key)||!TRACE_STATE_VALUE_PATTERN.test(memberValue)||keys.has(key))return!1;keys.add(key)}return!0}function isValidMcpBaggageValue(value){return BAGGAGE_VALUE_PATTERN.test(value)&&!INVALID_PERCENT_ENCODING_PATTERN.test(value)}function isValidMcpBaggageProperty(source){const property=trimOptionalWhitespace(source),separator=property.indexOf("="),key=trimOptionalWhitespace(separator>=0?property.slice(0,separator):property),value=separator>=0?trimOptionalWhitespace(property.slice(separator+1)):void 0;return BAGGAGE_KEY_PATTERN.test(key)&&(value===void 0||isValidMcpBaggageValue(value))}function parseMcpBaggageMember(source){const serialized=trimOptionalWhitespace(source),segments=serialized.split(";"),pair=segments[0],properties=segments.slice(1),separator=pair.indexOf("="),key=trimOptionalWhitespace(separator>0?pair.slice(0,separator):""),value=separator>0?trimOptionalWhitespace(pair.slice(separator+1)):"";if(!(!BAGGAGE_KEY_PATTERN.test(key)||!isValidMcpBaggageValue(value)||!properties.every(isValidMcpBaggageProperty)))return{key,serialized}}function filterMcpBaggage(baggage,allowlistEntries){if(baggage===void 0)return;if(typeof baggage!="string"||Buffer.byteLength(baggage,"utf8")>MAX_BAGGAGE_BYTES)throw new PmMcpAuthorizationError("Invalid MCP baggage",403);const allowlist=new Set(allowlistEntries),sources=baggage.split(",");if(sources.length>MAX_BAGGAGE_MEMBERS)throw new PmMcpAuthorizationError("Invalid MCP baggage",403);const entries=[];for(const source of sources){const entry=parseMcpBaggageMember(source);if(!entry)throw new PmMcpAuthorizationError("Invalid MCP baggage",403);allowlist.has(entry.key)&&entries.push(entry.serialized)}return entries.length>0?entries.join(","):void 0}function extractMcpTraceContext(params,options={}){const meta=isMcpRecord(params)&&isMcpRecord(params._meta)?params._meta:{},allowedBaggage=filterMcpBaggage(meta.baggage,options.baggageAllowlist??[]);return{...validateMcpTraceFields(meta),...allowedBaggage?{baggage:allowedBaggage}:{}}}function runWithMcpTraceContext(context,callback){return MCP_TRACE_CONTEXT_STORAGE.run(structuredClone(context),callback)}function getActiveMcpTraceContext(){const context=MCP_TRACE_CONTEXT_STORAGE.getStore();return context?{...context}:void 0}async function authorizeMcpHttpRequest(input){const resourceMetadataUrl=requireAbsoluteAuthorizationUrl(input.policy.resourceMetadataUrl,"protected resource metadata URL",!0).href,requiredScopes=[...new Set(input.policy.requiredScopes??[])];if(requiredScopes.some(scope=>!SCOPE_PATTERN.test(scope)))throw new PmMcpAuthorizationError("Invalid authorization scope",401);const challenge=`Bearer resource_metadata="${resourceMetadataUrl}"`;if(new URL(input.requestUrl,input.policy.resource).searchParams.has("access_token"))throw new PmMcpAuthorizationError("Access tokens must not appear in URI query parameters",401,challenge);const match=readHeader(input.headers,"authorization")?.match(/^Bearer ([^\s]+)$/iu);if(!match)throw new PmMcpAuthorizationError("Missing or malformed bearer token",401,challenge);const token=match[1];if(Buffer.byteLength(token,"utf8")>MAX_BEARER_TOKEN_BYTES)throw new PmMcpAuthorizationError("Missing or malformed bearer token",401,challenge);let claims;try{claims=await input.policy.verifyAccessToken(token)}catch{throw new PmMcpAuthorizationError("Invalid bearer token",401,challenge)}const audiences=Array.isArray(claims.audience)?claims.audience:[claims.audience];if(claims.issuer!==input.policy.issuer||!audiences.includes(input.policy.resource))throw new PmMcpAuthorizationError("Bearer token issuer or audience mismatch",401,challenge);const missingScopes=requiredScopes.filter(scope=>!claims.scopes.includes(scope));if(missingScopes.length>0)throw new PmMcpAuthorizationError("Bearer token has insufficient scope",403,`${challenge}, scope="${missingScopes.join(" ")}"`);return{...claims,audience:[...audiences],scopes:[...claims.scopes]}}function createMcpStaticBearerVerifier(input){const expected=createHash("sha256").update(input.token).digest();return token=>{const observed=createHash("sha256").update(token).digest();if(!timingSafeEqual(expected,observed))throw new PmMcpAuthorizationError("Invalid bearer token",401);return structuredClone(input.claims)}}export{PmMcpAuthorizationError,PmMcpIssuerCredentialStore,authorizeMcpHttpRequest,buildMcpAuthorizationDiscoveryUrls,buildMcpDynamicRegistrationMetadata,buildMcpProtectedResourceMetadata,createMcpStaticBearerVerifier,extractMcpTraceContext,getActiveMcpTraceContext,runWithMcpTraceContext,selectMcpClientRegistrationMode,validateMcpAuthorizationResponseIssuer,validateMcpAuthorizationServerMetadata,validateMcpClientMetadataDocument};
2
2
  //# sourceMappingURL=authorization.js.map
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="31eda153-a06e-51ef-a62f-f6dce09064d3")}catch(e2){}})();import{createHash,createHmac,randomBytes,timingSafeEqual}from"node:crypto";import{PM_COMMAND_CAPABILITY_CONTRACTS,PM_MCP_TOOL_COMMAND_CONTRACTS,resolvePmCommandCapabilityFamily,resolvePmCommandVisibilityTier}from"../agent-capability-contracts.js";import{PmCliError}from"../runtime-primitives.js";const PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION="dev.unbrained.pm/progressive-tool-discovery";const PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY=Object.freeze({version:1,discoveryTool:"pm_discover",canonicalResult:"structuredContent.result",compatibilityText:"pointer"});const PM_MCP_ENTRY_TOOL_NAMES=Object.freeze(["pm_discover","pm_next","pm_context","pm_search","pm_get"]);const DISCOVERY_WEIGHTS=Object.freeze({lexical:.4,semantic:.2,graph:.1,permission:.15,freshness:.05,usage:.1});const DISCOVERY_CACHE_INVALIDATIONS=Object.freeze(["profile_changed","tool_contract_changed","workspace_extension_changed","authorization_changed","ranking_signal_changed","cursor_integrity_key_rotated"]);const TIER_RANK={core:0,standard:1,full:2,internal:3};const SELECTABLE_TIERS=Object.freeze(["core","standard","full"]);const MCP_TOOL_PROFILES=new Set(["core","standard","full","custom"]);const CAPABILITY_FAMILIES=new Set(PM_COMMAND_CAPABILITY_CONTRACTS.map(({family})=>family));const PROCESS_CURSOR_INTEGRITY_KEY=randomBytes(32);function boundedDiscoveryString(value,field){if(typeof value!=="string"){throw new PmCliError(`pm tool discovery ${field} must be a string of at most 4096 Unicode characters.`,64)}const iterator=value[Symbol.iterator]();let count=0;for(let next=iterator.next();!next.done;next=iterator.next()){count+=1;if(count>4096){throw new PmCliError(`pm tool discovery ${field} must be a string of at most 4096 Unicode characters.`,64)}}return value}function discoveryLimit(value){if(!Number.isInteger(value)||Number(value)<1||Number(value)>100){throw new PmCliError("pm tool discovery limit must be from 1 through 100.",64)}return Number(value)}function discoveryOutputBudget(value){if(value!=="unbounded"&&(!Number.isInteger(value)||Number(value)<128)){throw new PmCliError("pm tool discovery outputBudget must be unbounded or an integer of at least 128.",64)}return value==="unbounded"?value:Number(value)}function discoveryIncludeSchema(value){if(value!==void 0&&typeof value!=="boolean"){throw new PmCliError("pm tool discovery includeSchema must be a boolean.",64)}return value===true}function validateDiscoveryOptionsContainer(value){if(value===null||typeof value!=="object"||Array.isArray(value)){throw new PmCliError("pm tool discovery options must be an object.",64)}}function validateDiscoveryCandidates(candidates){if(!Array.isArray(candidates)){throw new PmCliError("pm tool discovery candidates must be an array.",64)}for(const[index,candidate]of candidates.entries()){if(candidate===null||typeof candidate!=="object"||Array.isArray(candidate)){throw new PmCliError(`pm tool discovery candidate ${index} must be an object.`,64)}if(typeof candidate.name!=="string"||candidate.name.trim().length===0){throw new PmCliError(`pm tool discovery candidate ${index} name must be a non-empty string.`,64)}if(typeof candidate.description!=="string"||candidate.description.trim().length===0){throw new PmCliError(`pm tool discovery candidate ${index} description must be a non-empty string.`,64)}if(candidate.inputSchema===null||typeof candidate.inputSchema!=="object"||Array.isArray(candidate.inputSchema)){throw new PmCliError(`pm tool discovery candidate ${index} inputSchema must be an object.`,64)}if(candidate.authorized!==void 0&&typeof candidate.authorized!=="boolean"){throw new PmCliError(`pm tool discovery candidate ${index} authorized must be a boolean.`,64)}}}function parsePmToolDiscoveryOptions(input){validateDiscoveryOptionsContainer(input);if(input.family!==void 0&&(typeof input.family!=="string"||!CAPABILITY_FAMILIES.has(input.family))){throw new PmCliError("pm tool discovery family must be a declared capability family.",64)}if(input.tier!==void 0&&(typeof input.tier!=="string"||!SELECTABLE_TIERS.includes(input.tier))){throw new PmCliError("pm tool discovery tier must be core, standard, or full.",64)}return{...input.query!==void 0?{query:boundedDiscoveryString(input.query,"query")}:{},...input.family!==void 0?{family:input.family}:{},...input.tier!==void 0?{tier:input.tier}:{},...input.limit!==void 0?{limit:discoveryLimit(input.limit)}:{},...input.cursor!==void 0?{cursor:boundedDiscoveryString(input.cursor,"cursor")}:{},...input.includeSchema!==void 0?{includeSchema:discoveryIncludeSchema(input.includeSchema)}:{},...input.outputBudget!==void 0?{outputBudget:discoveryOutputBudget(input.outputBudget)}:{}}}function normalizedUnitInterval(value){if(value===void 0||!Number.isFinite(value))return 0;return Math.min(1,Math.max(0,value))}function normalizedSearchTokens(value){return[...new Set(value.toLowerCase().match(/[a-z0-9]+/gu)??[])].sort()}function lexicalRelevance(query,text){const queryTokens=normalizedSearchTokens(query);if(queryTokens.length===0)return 0;const targetTokens=new Set(normalizedSearchTokens(text));const matched=queryTokens.filter(token=>targetTokens.has(token)).length;const exactBonus=text.toLowerCase().includes(query.toLowerCase())?.25:0;return Math.min(1,matched/queryTokens.length+exactBonus)}function semanticRelevance(query,text){const queryTokens=normalizedSearchTokens(query);if(queryTokens.length===0)return 0;const target=text.toLowerCase();const targetTokens=normalizedSearchTokens(text);const related=queryTokens.filter(queryToken=>targetTokens.some(targetToken=>targetToken.startsWith(queryToken)||queryToken.startsWith(targetToken))).length;const phraseBonus=target.includes(query.toLowerCase())?.2:0;return Math.min(1,related/queryTokens.length+phraseBonus)}function hashDiscoveryValue(value){return createHash("sha256").update(JSON.stringify(value)).digest("hex").slice(0,24)}function cursorSignature(fingerprint,offset,integrityKey){return createHmac("sha256",integrityKey).update(JSON.stringify({version:1,fingerprint,offset})).digest("base64url")}function encodeDiscoveryCursor(fingerprint,offset,integrityKey){const cursor={version:1,offset,signature:cursorSignature(fingerprint,offset,integrityKey)};return Buffer.from(JSON.stringify(cursor),"utf8").toString("base64url")}function decodeDiscoveryCursor(value,fingerprint,total,integrityKey){if(value===void 0)return 0;try{const decoded=JSON.parse(Buffer.from(value,"base64url").toString("utf8"));if(decoded.version!==1||!Number.isInteger(decoded.offset)||(decoded.offset??-1)<0||Number(decoded.offset)>total||typeof decoded.signature!=="string"){throw new Error("cursor fields do not match the request")}const expectedSignature=Buffer.from(cursorSignature(fingerprint,decoded.offset,integrityKey),"base64url");const suppliedSignature=Buffer.from(decoded.signature,"base64url");if(suppliedSignature.length!==expectedSignature.length||!timingSafeEqual(suppliedSignature,expectedSignature)){throw new Error("cursor signature does not match the request")}return decoded.offset}catch(error){throw new PmCliError("Invalid or stale pm tool discovery cursor; restart discovery without cursor.",64,{reason:String(error)})}}function appliedSignal(value,weight,source){return{value:normalizedUnitInterval(value),weight,available:source!=="unavailable",source}}function hostOrComputedSignal(hostValue,computedValue,weight){return appliedSignal(hostValue??computedValue,weight,hostValue===void 0?"computed":"host")}function buildRankedRow(candidate,query,includeSchema){const command=Object.hasOwn(PM_MCP_TOOL_COMMAND_CONTRACTS,candidate.name)?PM_MCP_TOOL_COMMAND_CONTRACTS[candidate.name]:"help";const family=resolvePmCommandCapabilityFamily(command);const searchableText=`${candidate.name} ${candidate.description} ${command} ${family}`;const lexical=lexicalRelevance(query,searchableText);const queryTokens=new Set(normalizedSearchTokens(query));const signals={lexical:appliedSignal(lexical,DISCOVERY_WEIGHTS.lexical,"computed"),semantic:hostOrComputedSignal(candidate.signals?.semantic,semanticRelevance(query,searchableText),DISCOVERY_WEIGHTS.semantic),graph:hostOrComputedSignal(candidate.signals?.graph,queryTokens.has(family)||queryTokens.has(command)?1:0,DISCOVERY_WEIGHTS.graph),permission:appliedSignal(1,DISCOVERY_WEIGHTS.permission,"authorization"),freshness:hostOrComputedSignal(candidate.signals?.freshness,1,DISCOVERY_WEIGHTS.freshness),usage:hostOrComputedSignal(candidate.signals?.usage,PM_MCP_ENTRY_TOOL_NAMES.includes(candidate.name)?1:0,DISCOVERY_WEIGHTS.usage)};const score=Object.values(signals).reduce((total,signal)=>total+signal.value*signal.weight,0);return{name:candidate.name,description:candidate.description,command,tier:resolvePmCommandVisibilityTier(command),family,score:Number(score.toFixed(6)),signals,...includeSchema?{input_schema:structuredClone(candidate.inputSchema)}:{}}}function validateDiscoveryFilters(options){if(options.cursorIntegrityKey!==void 0&&(!(options.cursorIntegrityKey instanceof Uint8Array)||options.cursorIntegrityKey.byteLength<32)){throw new PmCliError("pm tool discovery cursorIntegrityKey must contain at least 32 bytes.",64)}if(options.tier!==void 0&&(typeof options.tier!=="string"||!SELECTABLE_TIERS.includes(options.tier))){throw new PmCliError("pm tool discovery tier must be core, standard, or full.",64)}if(options.family!==void 0&&(typeof options.family!=="string"||!CAPABILITY_FAMILIES.has(options.family))){throw new PmCliError("pm tool discovery family must be a declared capability family.",64)}if(options.profile!==void 0&&(typeof options.profile!=="string"||!MCP_TOOL_PROFILES.has(options.profile))){throw new PmCliError("pm tool discovery profile must be core, standard, full, or custom.",64)}}function resolveDiscoveryRequest(options){const rawQuery=boundedDiscoveryString(options.query===void 0?"":options.query,"query");const query=rawQuery.trim().replace(/\s+/gu," ");boundedDiscoveryString(options.cursor===void 0?"":options.cursor,"cursor");const limit=discoveryLimit(options.limit===void 0?10:options.limit);const budget=discoveryOutputBudget(options.outputBudget===void 0?1200:options.outputBudget);validateDiscoveryFilters(options);return{query,includeSchema:discoveryIncludeSchema(options.includeSchema),limit,budget,maximumTier:TIER_RANK[options.tier??"full"],profile:options.profile===void 0?"core":options.profile}}function estimateDiscoveryResultTokens(resultWithoutCost,budget,serializedToolRowsBytes){const toolRowsBytes=serializedToolRowsBytes??resultWithoutCost.tools.reduce((total,row,index)=>total+(index===0?0:1)+Buffer.byteLength(JSON.stringify(row),"utf8"),0);const emptyToolsResult={...resultWithoutCost,tools:[]};let estimatedTokens=0;for(let iteration=0;iteration<4;iteration+=1){const envelopeBytes=Buffer.byteLength(JSON.stringify({...emptyToolsResult,token_cost:{estimated_tokens:estimatedTokens,budget,within_budget:true}}),"utf8");const nextEstimate=Math.ceil((envelopeBytes+toolRowsBytes)/4);if(nextEstimate===estimatedTokens)break;estimatedTokens=nextEstimate}return estimatedTokens}function rankedDiscoveryRows(candidates,options,request){return candidates.filter(candidate=>candidate.authorized!==false).map(candidate=>buildRankedRow(candidate,request.query,request.includeSchema)).filter(row=>row.tier!=="internal"&&TIER_RANK[row.tier]<=request.maximumTier&&(options.family===void 0||row.family===options.family)).sort((left,right)=>right.score-left.score||(left.name<right.name?-1:left.name>right.name?1:0))}function rowsWithinDiscoveryBudget(candidates,budget,buildResultWithoutCost){if(budget==="unbounded")return[...candidates];const selected=[];let serializedToolRowsBytes=0;for(const[index,row]of candidates.entries()){const candidateRowsBytes=serializedToolRowsBytes+(index===0?0:1)+Buffer.byteLength(JSON.stringify(row),"utf8");const estimatedTokens=estimateDiscoveryResultTokens(buildResultWithoutCost(index+1),budget,candidateRowsBytes);if(estimatedTokens>budget)break;selected.push(row);serializedToolRowsBytes=candidateRowsBytes}return selected}function discoverPmTools(candidates,options={}){validateDiscoveryCandidates(candidates);validateDiscoveryOptionsContainer(options);const request=resolveDiscoveryRequest(options);const cursorIntegrityKey=options.cursorIntegrityKey??PROCESS_CURSOR_INTEGRITY_KEY;const ranked=rankedDiscoveryRows(candidates,options,request);const fingerprint=hashDiscoveryValue({query:request.query,family:options.family??null,tier:options.tier??"full",includeSchema:request.includeSchema,profile:request.profile,ranked});const offset=decodeDiscoveryCursor(options.cursor,fingerprint,ranked.length,cursorIntegrityKey);const pageCandidates=ranked.slice(offset,offset+request.limit);const omitted=[];if(!request.includeSchema){omitted.push({name:"input_schema",reason:"compact_projection",restore_with:"Set includeSchema=true."})}if(offset+request.limit<ranked.length){omitted.push({name:"tools",reason:"limit",restore_with:"Continue with next_cursor or increase limit."})}const base={result_type:"pm_tool_discovery",contract_version:1,query:request.query,profile:request.profile,total:ranked.length,ranking_policy:{version:1,formula:"weighted_sum_then_name",weights:DISCOVERY_WEIGHTS},cache:{key:hashDiscoveryValue({fingerprint,cursorIntegrityKey:createHash("sha256").update(cursorIntegrityKey).digest("hex"),limit:request.limit,offset,budget:request.budget}),ttl_ms:3e4,scope:"private",invalidates_on:DISCOVERY_CACHE_INVALIDATIONS}};const buildResultWithoutCost=(selected2,selectedCount=selected2.length)=>{const endOffset=offset+selectedCount;const hasMore=endOffset<ranked.length;const resultOmissions=[...omitted];if(selectedCount<pageCandidates.length){resultOmissions.push({name:"tools",reason:"token_budget",restore_with:"Continue with next_cursor or increase outputBudget."})}const resultWithoutCost={...base,tools:[...selected2],returned:selectedCount,has_more:hasMore,...hasMore?{next_cursor:encodeDiscoveryCursor(fingerprint,endOffset,cursorIntegrityKey)}:{},omission_receipt:{has_omissions:resultOmissions.length>0,omitted:resultOmissions}};return resultWithoutCost};const buildResult=selected2=>{const resultWithoutCost=buildResultWithoutCost(selected2);const estimatedTokens=estimateDiscoveryResultTokens(resultWithoutCost,request.budget);return{...resultWithoutCost,token_cost:{estimated_tokens:estimatedTokens,budget:request.budget,within_budget:request.budget==="unbounded"||estimatedTokens<=request.budget}}};const selected=rowsWithinDiscoveryBudget(pageCandidates,request.budget,selectedCount=>buildResultWithoutCost([],selectedCount));const result=buildResult(selected);if(pageCandidates.length>0&&selected.length===0){const oneRowCost=buildResult([pageCandidates[0]]).token_cost.estimated_tokens;throw new PmCliError(`pm tool discovery outputBudget is too small to return a tool; increase it to at least ${oneRowCost}.`,64,{required:String(oneRowCost)})}if(request.budget!=="unbounded"&&result.token_cost.estimated_tokens>request.budget){throw new PmCliError(`pm tool discovery outputBudget is too small; at least ${result.token_cost.estimated_tokens} estimated tokens are required for this page.`,64,{required:String(result.token_cost.estimated_tokens)})}return result}export{PM_MCP_ENTRY_TOOL_NAMES,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION,PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY,discoverPmTools,parsePmToolDiscoveryOptions};
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]="837ee381-0838-55d3-bcdf-7352fb76661d")}catch{}})();import{createHash,createHmac,randomBytes,timingSafeEqual}from"node:crypto";import{PM_COMMAND_CAPABILITY_CONTRACTS,PM_MCP_TOOL_COMMAND_CONTRACTS,resolvePmCommandCapabilityFamily,resolvePmCommandVisibilityTier}from"../agent-capability-contracts.js";import{PmCliError}from"../runtime-primitives.js";const PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION="dev.unbrained.pm/progressive-tool-discovery",PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY=Object.freeze({version:1,discoveryTool:"pm_discover",canonicalResult:"structuredContent.result",compatibilityText:"pointer"}),PM_MCP_ENTRY_TOOL_NAMES=Object.freeze(["pm_discover","pm_next","pm_context","pm_search","pm_get"]),DISCOVERY_WEIGHTS=Object.freeze({lexical:.4,semantic:.2,graph:.1,permission:.15,freshness:.05,usage:.1}),DISCOVERY_CACHE_INVALIDATIONS=Object.freeze(["profile_changed","tool_contract_changed","workspace_extension_changed","authorization_changed","ranking_signal_changed","cursor_integrity_key_rotated"]),TIER_RANK={core:0,standard:1,full:2,internal:3},SELECTABLE_TIERS=Object.freeze(["core","standard","full"]),MCP_TOOL_PROFILES=new Set(["core","standard","full","custom"]),CAPABILITY_FAMILIES=new Set(PM_COMMAND_CAPABILITY_CONTRACTS.map(({family})=>family)),PROCESS_CURSOR_INTEGRITY_KEY=randomBytes(32);function boundedDiscoveryString(value,field){if(typeof value!="string")throw new PmCliError(`pm tool discovery ${field} must be a string of at most 4096 Unicode characters.`,64);const iterator=value[Symbol.iterator]();let count=0;for(let next=iterator.next();!next.done;next=iterator.next())if(count+=1,count>4096)throw new PmCliError(`pm tool discovery ${field} must be a string of at most 4096 Unicode characters.`,64);return value}function discoveryLimit(value){if(!Number.isInteger(value)||Number(value)<1||Number(value)>100)throw new PmCliError("pm tool discovery limit must be from 1 through 100.",64);return Number(value)}function discoveryOutputBudget(value){if(value!=="unbounded"&&(!Number.isInteger(value)||Number(value)<128))throw new PmCliError("pm tool discovery outputBudget must be unbounded or an integer of at least 128.",64);return value==="unbounded"?value:Number(value)}function discoveryIncludeSchema(value){if(value!==void 0&&typeof value!="boolean")throw new PmCliError("pm tool discovery includeSchema must be a boolean.",64);return value===!0}function validateDiscoveryOptionsContainer(value){if(value===null||typeof value!="object"||Array.isArray(value))throw new PmCliError("pm tool discovery options must be an object.",64)}function validateDiscoveryCandidates(candidates){if(!Array.isArray(candidates))throw new PmCliError("pm tool discovery candidates must be an array.",64);for(const[index,candidate]of candidates.entries()){if(candidate===null||typeof candidate!="object"||Array.isArray(candidate))throw new PmCliError(`pm tool discovery candidate ${index} must be an object.`,64);if(typeof candidate.name!="string"||candidate.name.trim().length===0)throw new PmCliError(`pm tool discovery candidate ${index} name must be a non-empty string.`,64);if(typeof candidate.description!="string"||candidate.description.trim().length===0)throw new PmCliError(`pm tool discovery candidate ${index} description must be a non-empty string.`,64);if(candidate.inputSchema===null||typeof candidate.inputSchema!="object"||Array.isArray(candidate.inputSchema))throw new PmCliError(`pm tool discovery candidate ${index} inputSchema must be an object.`,64);if(candidate.authorized!==void 0&&typeof candidate.authorized!="boolean")throw new PmCliError(`pm tool discovery candidate ${index} authorized must be a boolean.`,64)}}function parsePmToolDiscoveryOptions(input){if(validateDiscoveryOptionsContainer(input),input.family!==void 0&&(typeof input.family!="string"||!CAPABILITY_FAMILIES.has(input.family)))throw new PmCliError("pm tool discovery family must be a declared capability family.",64);if(input.tier!==void 0&&(typeof input.tier!="string"||!SELECTABLE_TIERS.includes(input.tier)))throw new PmCliError("pm tool discovery tier must be core, standard, or full.",64);return{...input.query!==void 0?{query:boundedDiscoveryString(input.query,"query")}:{},...input.family!==void 0?{family:input.family}:{},...input.tier!==void 0?{tier:input.tier}:{},...input.limit!==void 0?{limit:discoveryLimit(input.limit)}:{},...input.cursor!==void 0?{cursor:boundedDiscoveryString(input.cursor,"cursor")}:{},...input.includeSchema!==void 0?{includeSchema:discoveryIncludeSchema(input.includeSchema)}:{},...input.outputBudget!==void 0?{outputBudget:discoveryOutputBudget(input.outputBudget)}:{}}}function normalizedUnitInterval(value){return value===void 0||!Number.isFinite(value)?0:Math.min(1,Math.max(0,value))}function normalizedSearchTokens(value){return[...new Set(value.toLowerCase().match(/[a-z0-9]+/gu)??[])].sort()}function lexicalRelevance(query,text){const queryTokens=normalizedSearchTokens(query);if(queryTokens.length===0)return 0;const targetTokens=new Set(normalizedSearchTokens(text)),matched=queryTokens.filter(token=>targetTokens.has(token)).length,exactBonus=text.toLowerCase().includes(query.toLowerCase())?.25:0;return Math.min(1,matched/queryTokens.length+exactBonus)}function semanticRelevance(query,text){const queryTokens=normalizedSearchTokens(query);if(queryTokens.length===0)return 0;const target=text.toLowerCase(),targetTokens=normalizedSearchTokens(text),related=queryTokens.filter(queryToken=>targetTokens.some(targetToken=>targetToken.startsWith(queryToken)||queryToken.startsWith(targetToken))).length,phraseBonus=target.includes(query.toLowerCase())?.2:0;return Math.min(1,related/queryTokens.length+phraseBonus)}function hashDiscoveryValue(value){return createHash("sha256").update(JSON.stringify(value)).digest("hex").slice(0,24)}function cursorSignature(fingerprint,offset,integrityKey){return createHmac("sha256",integrityKey).update(JSON.stringify({version:1,fingerprint,offset})).digest("base64url")}function encodeDiscoveryCursor(fingerprint,offset,integrityKey){const cursor={version:1,offset,signature:cursorSignature(fingerprint,offset,integrityKey)};return Buffer.from(JSON.stringify(cursor),"utf8").toString("base64url")}function decodeDiscoveryCursor(value,fingerprint,total,integrityKey){if(value===void 0)return 0;try{const decoded=JSON.parse(Buffer.from(value,"base64url").toString("utf8"));if(decoded.version!==1||!Number.isInteger(decoded.offset)||(decoded.offset??-1)<0||Number(decoded.offset)>total||typeof decoded.signature!="string")throw new Error("cursor fields do not match the request");const expectedSignature=Buffer.from(cursorSignature(fingerprint,decoded.offset,integrityKey),"base64url"),suppliedSignature=Buffer.from(decoded.signature,"base64url");if(suppliedSignature.length!==expectedSignature.length||!timingSafeEqual(suppliedSignature,expectedSignature))throw new Error("cursor signature does not match the request");return decoded.offset}catch(error){throw new PmCliError("Invalid or stale pm tool discovery cursor; restart discovery without cursor.",64,{reason:String(error)})}}function appliedSignal(value,weight,source){return{value:normalizedUnitInterval(value),weight,available:source!=="unavailable",source}}function hostOrComputedSignal(hostValue,computedValue,weight){return appliedSignal(hostValue??computedValue,weight,hostValue===void 0?"computed":"host")}function buildRankedRow(candidate,query,includeSchema){const command=Object.hasOwn(PM_MCP_TOOL_COMMAND_CONTRACTS,candidate.name)?PM_MCP_TOOL_COMMAND_CONTRACTS[candidate.name]:"help",family=resolvePmCommandCapabilityFamily(command),searchableText=`${candidate.name} ${candidate.description} ${command} ${family}`,lexical=lexicalRelevance(query,searchableText),queryTokens=new Set(normalizedSearchTokens(query)),signals={lexical:appliedSignal(lexical,DISCOVERY_WEIGHTS.lexical,"computed"),semantic:hostOrComputedSignal(candidate.signals?.semantic,semanticRelevance(query,searchableText),DISCOVERY_WEIGHTS.semantic),graph:hostOrComputedSignal(candidate.signals?.graph,queryTokens.has(family)||queryTokens.has(command)?1:0,DISCOVERY_WEIGHTS.graph),permission:appliedSignal(1,DISCOVERY_WEIGHTS.permission,"authorization"),freshness:hostOrComputedSignal(candidate.signals?.freshness,1,DISCOVERY_WEIGHTS.freshness),usage:hostOrComputedSignal(candidate.signals?.usage,PM_MCP_ENTRY_TOOL_NAMES.includes(candidate.name)?1:0,DISCOVERY_WEIGHTS.usage)},score=Object.values(signals).reduce((total,signal)=>total+signal.value*signal.weight,0);return{name:candidate.name,description:candidate.description,command,tier:resolvePmCommandVisibilityTier(command),family,score:Number(score.toFixed(6)),signals,...includeSchema?{input_schema:structuredClone(candidate.inputSchema)}:{}}}function validateDiscoveryFilters(options){if(options.cursorIntegrityKey!==void 0&&(!(options.cursorIntegrityKey instanceof Uint8Array)||options.cursorIntegrityKey.byteLength<32))throw new PmCliError("pm tool discovery cursorIntegrityKey must contain at least 32 bytes.",64);if(options.tier!==void 0&&(typeof options.tier!="string"||!SELECTABLE_TIERS.includes(options.tier)))throw new PmCliError("pm tool discovery tier must be core, standard, or full.",64);if(options.family!==void 0&&(typeof options.family!="string"||!CAPABILITY_FAMILIES.has(options.family)))throw new PmCliError("pm tool discovery family must be a declared capability family.",64);if(options.profile!==void 0&&(typeof options.profile!="string"||!MCP_TOOL_PROFILES.has(options.profile)))throw new PmCliError("pm tool discovery profile must be core, standard, full, or custom.",64)}function resolveDiscoveryRequest(options){const query=boundedDiscoveryString(options.query===void 0?"":options.query,"query").trim().replace(/\s+/gu," ");boundedDiscoveryString(options.cursor===void 0?"":options.cursor,"cursor");const limit=discoveryLimit(options.limit===void 0?10:options.limit),budget=discoveryOutputBudget(options.outputBudget===void 0?1200:options.outputBudget);return validateDiscoveryFilters(options),{query,includeSchema:discoveryIncludeSchema(options.includeSchema),limit,budget,maximumTier:TIER_RANK[options.tier??"full"],profile:options.profile===void 0?"core":options.profile}}function estimateDiscoveryResultTokens(resultWithoutCost,budget,serializedToolRowsBytes){const toolRowsBytes=serializedToolRowsBytes??resultWithoutCost.tools.reduce((total,row,index)=>total+(index===0?0:1)+Buffer.byteLength(JSON.stringify(row),"utf8"),0),emptyToolsResult={...resultWithoutCost,tools:[]};let estimatedTokens=0;for(let iteration=0;iteration<4;iteration+=1){const envelopeBytes=Buffer.byteLength(JSON.stringify({...emptyToolsResult,token_cost:{estimated_tokens:estimatedTokens,budget,within_budget:!0}}),"utf8"),nextEstimate=Math.ceil((envelopeBytes+toolRowsBytes)/4);if(nextEstimate===estimatedTokens)break;estimatedTokens=nextEstimate}return estimatedTokens}function rankedDiscoveryRows(candidates,options,request){return candidates.filter(candidate=>candidate.authorized!==!1).map(candidate=>buildRankedRow(candidate,request.query,request.includeSchema)).filter(row=>row.tier!=="internal"&&TIER_RANK[row.tier]<=request.maximumTier&&(options.family===void 0||row.family===options.family)).sort((left,right)=>right.score-left.score||(left.name<right.name?-1:left.name>right.name?1:0))}function rowsWithinDiscoveryBudget(candidates,budget,buildResultWithoutCost){if(budget==="unbounded")return[...candidates];const selected=[];let serializedToolRowsBytes=0;for(const[index,row]of candidates.entries()){const candidateRowsBytes=serializedToolRowsBytes+(index===0?0:1)+Buffer.byteLength(JSON.stringify(row),"utf8");if(estimateDiscoveryResultTokens(buildResultWithoutCost(index+1),budget,candidateRowsBytes)>budget)break;selected.push(row),serializedToolRowsBytes=candidateRowsBytes}return selected}function discoverPmTools(candidates,options={}){validateDiscoveryCandidates(candidates),validateDiscoveryOptionsContainer(options);const request=resolveDiscoveryRequest(options),cursorIntegrityKey=options.cursorIntegrityKey??PROCESS_CURSOR_INTEGRITY_KEY,ranked=rankedDiscoveryRows(candidates,options,request),fingerprint=hashDiscoveryValue({query:request.query,family:options.family??null,tier:options.tier??"full",includeSchema:request.includeSchema,profile:request.profile,ranked}),offset=decodeDiscoveryCursor(options.cursor,fingerprint,ranked.length,cursorIntegrityKey),pageCandidates=ranked.slice(offset,offset+request.limit),omitted=[];request.includeSchema||omitted.push({name:"input_schema",reason:"compact_projection",restore_with:"Set includeSchema=true."}),offset+request.limit<ranked.length&&omitted.push({name:"tools",reason:"limit",restore_with:"Continue with next_cursor or increase limit."});const base={result_type:"pm_tool_discovery",contract_version:1,query:request.query,profile:request.profile,total:ranked.length,ranking_policy:{version:1,formula:"weighted_sum_then_name",weights:DISCOVERY_WEIGHTS},cache:{key:hashDiscoveryValue({fingerprint,cursorIntegrityKey:createHash("sha256").update(cursorIntegrityKey).digest("hex"),limit:request.limit,offset,budget:request.budget}),ttl_ms:3e4,scope:"private",invalidates_on:DISCOVERY_CACHE_INVALIDATIONS}},buildResultWithoutCost=(selected2,selectedCount=selected2.length)=>{const endOffset=offset+selectedCount,hasMore=endOffset<ranked.length,resultOmissions=[...omitted];return selectedCount<pageCandidates.length&&resultOmissions.push({name:"tools",reason:"token_budget",restore_with:"Continue with next_cursor or increase outputBudget."}),{...base,tools:[...selected2],returned:selectedCount,has_more:hasMore,...hasMore?{next_cursor:encodeDiscoveryCursor(fingerprint,endOffset,cursorIntegrityKey)}:{},omission_receipt:{has_omissions:resultOmissions.length>0,omitted:resultOmissions}}},buildResult=selected2=>{const resultWithoutCost=buildResultWithoutCost(selected2),estimatedTokens=estimateDiscoveryResultTokens(resultWithoutCost,request.budget);return{...resultWithoutCost,token_cost:{estimated_tokens:estimatedTokens,budget:request.budget,within_budget:request.budget==="unbounded"||estimatedTokens<=request.budget}}},selected=rowsWithinDiscoveryBudget(pageCandidates,request.budget,selectedCount=>buildResultWithoutCost([],selectedCount)),result=buildResult(selected);if(pageCandidates.length>0&&selected.length===0){const oneRowCost=buildResult([pageCandidates[0]]).token_cost.estimated_tokens;throw new PmCliError(`pm tool discovery outputBudget is too small to return a tool; increase it to at least ${oneRowCost}.`,64,{required:String(oneRowCost)})}if(request.budget!=="unbounded"&&result.token_cost.estimated_tokens>request.budget)throw new PmCliError(`pm tool discovery outputBudget is too small; at least ${result.token_cost.estimated_tokens} estimated tokens are required for this page.`,64,{required:String(result.token_cost.estimated_tokens)});return result}export{PM_MCP_ENTRY_TOOL_NAMES,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION,PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY,discoverPmTools,parsePmToolDiscoveryOptions};
2
2
  //# sourceMappingURL=discovery.js.map
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6505e714-d1f3-5794-88c8-51c1644acec9")}catch(e2){}})();import{createHash,createHmac,timingSafeEqual}from"node:crypto";import{PM_MCP_ERROR_CODES,PM_MCP_META_KEYS,PmMcpProtocolError,isMcpRecord}from"./protocol.js";const PM_MCP_INPUT_REQUEST_METHODS=["elicitation/create","roots/list","sampling/createMessage"];class PmMcpInputRequiredError extends Error{inputRequests;requestState;constructor(input){super("MCP operation requires additional input");this.name="PmMcpInputRequiredError";this.inputRequests=input.inputRequests;this.requestState=input.requestState}}const INPUT_KEY_PATTERN=/^[a-zA-Z][a-zA-Z0-9_.-]{0,63}$/u;const MAX_INPUT_REQUESTS=32;const MAX_INPUT_PAYLOAD_BYTES=64*1024;const MAX_REQUEST_STATE_BYTES=16*1024;const DEFAULT_SCHEMA_BOUNDS={maxBytes:256*1024,maxDepth:32,maxNodes:4096};function inputCapability(method){if(method==="elicitation/create")return"elicitation";if(method==="sampling/createMessage")return"sampling";return"roots"}function assertBoundedJson(value,maximumBytes,field){let serialized;try{serialized=JSON.stringify(value)}catch{throw new PmMcpProtocolError(`Invalid ${field}: value is not JSON serializable`,PM_MCP_ERROR_CODES.invalidParams,{field})}if(Buffer.byteLength(serialized,"utf8")>maximumBytes){throw new PmMcpProtocolError(`Invalid ${field}: payload exceeds the protocol bound`,PM_MCP_ERROR_CODES.invalidParams,{field,maximumBytes})}}function parseMcpInputRequests(value,requestContext){if(!isMcpRecord(value)){throw new PmMcpProtocolError("Invalid MCP inputRequests",PM_MCP_ERROR_CODES.invalidParams,{field:"inputRequests",expected:"object"})}const entries=Object.entries(value);if(entries.length===0||entries.length>MAX_INPUT_REQUESTS){throw new PmMcpProtocolError("Invalid MCP inputRequests count",PM_MCP_ERROR_CODES.invalidParams,{minimum:1,maximum:MAX_INPUT_REQUESTS,observed:entries.length})}const parsed={};for(const[key,request]of entries){if(!INPUT_KEY_PATTERN.test(key)||!isMcpRecord(request)){throw new PmMcpProtocolError("Invalid MCP input request entry",PM_MCP_ERROR_CODES.invalidParams,{field:`inputRequests.${key}`})}const method=request.method;if(typeof method!=="string"||!PM_MCP_INPUT_REQUEST_METHODS.includes(method)){throw new PmMcpProtocolError("Unsupported MCP input request method",PM_MCP_ERROR_CODES.invalidParams,{field:`inputRequests.${key}.method`,method:method??null})}const capability=inputCapability(method);if(!Object.prototype.hasOwnProperty.call(requestContext.clientCapabilities,capability)){throw new PmMcpProtocolError("Missing required client capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:{[capability]:{}}})}if(!isMcpRecord(request.params)){throw new PmMcpProtocolError("Invalid MCP input request parameters",PM_MCP_ERROR_CODES.invalidParams,{field:`inputRequests.${key}.params`,expected:"object"})}parsed[key]={method,params:structuredClone(request.params)}}assertBoundedJson(parsed,MAX_INPUT_PAYLOAD_BYTES,"inputRequests");return parsed}function parseMcpInputResponses(value){if(!isMcpRecord(value)){throw new PmMcpProtocolError("Invalid MCP inputResponses",PM_MCP_ERROR_CODES.invalidParams,{field:"inputResponses",expected:"object"})}const entries=Object.entries(value);if(entries.length>MAX_INPUT_REQUESTS){throw new PmMcpProtocolError("Invalid MCP inputResponses count",PM_MCP_ERROR_CODES.invalidParams,{maximum:MAX_INPUT_REQUESTS,observed:entries.length})}const parsed={};for(const[key,response]of entries){if(!INPUT_KEY_PATTERN.test(key)||!isMcpRecord(response)){throw new PmMcpProtocolError("Invalid MCP input response entry",PM_MCP_ERROR_CODES.invalidParams,{field:`inputResponses.${key}`})}parsed[key]=structuredClone(response)}assertBoundedJson(parsed,MAX_INPUT_PAYLOAD_BYTES,"inputResponses");return parsed}function buildMcpInputRequiredResult(input){const requestState=input.requestState?.trim();if(requestState&&Buffer.byteLength(requestState,"utf8")>MAX_REQUEST_STATE_BYTES){throw new PmMcpProtocolError("Invalid MCP requestState: payload exceeds the protocol bound",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState",maximumBytes:MAX_REQUEST_STATE_BYTES})}const inputRequests=input.inputRequests===void 0?void 0:parseMcpInputRequests(input.inputRequests,input.requestContext);if(inputRequests===void 0&&!requestState){throw new PmMcpProtocolError("InputRequiredResult requires inputRequests or requestState",PM_MCP_ERROR_CODES.invalidParams,{requiredAnyOf:["inputRequests","requestState"]})}return{resultType:"input_required",...inputRequests?{inputRequests}:{},...requestState?{requestState}:{},_meta:{[PM_MCP_META_KEYS.serverInfo]:{...input.serverInfo}}}}function requestStateSecret(secret){const bytes=Buffer.from(secret);if(bytes.byteLength<32){throw new PmMcpProtocolError("MCP requestState signing key must contain at least 32 bytes",PM_MCP_ERROR_CODES.invalidParams,{minimumBytes:32})}return bytes}function sealMcpRequestState(payload,secret){if(!Number.isSafeInteger(payload.expiresAt)||payload.expiresAt<=0||payload.method.trim().length===0||payload.parameterDigest.trim().length===0||payload.principal.trim().length===0){throw new PmMcpProtocolError("Invalid MCP requestState payload",PM_MCP_ERROR_CODES.invalidParams)}const encoded=Buffer.from(JSON.stringify({version:1,...payload}),"utf8");if(encoded.byteLength>MAX_REQUEST_STATE_BYTES/2){throw new PmMcpProtocolError("MCP requestState payload exceeds the protocol bound",PM_MCP_ERROR_CODES.invalidParams,{maximumBytes:MAX_REQUEST_STATE_BYTES/2})}const body=encoded.toString("base64url");const signature=createHmac("sha256",requestStateSecret(secret)).update(body).digest("base64url");return`${body}.${signature}`}function parseMcpRequestStatePayload(decoded){if(!isMcpRecord(decoded)||decoded.version!==1){throw new PmMcpProtocolError("Invalid MCP requestState payload",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"})}const{expiresAt,method,parameterDigest,principal,state}=decoded;if(typeof expiresAt!=="number"||!Number.isSafeInteger(expiresAt)){throw new PmMcpProtocolError("Invalid MCP requestState payload",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"})}if(typeof method!=="string"||typeof parameterDigest!=="string"||typeof principal!=="string"){throw new PmMcpProtocolError("Invalid MCP requestState payload",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"})}return{expiresAt,method,parameterDigest,principal,state}}function openMcpRequestState(value,secret,expected){const[body,signature,extra]=value.split(".");if(!body||!signature||extra!==void 0){throw new PmMcpProtocolError("Invalid MCP requestState encoding",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"})}const observed=Buffer.from(signature,"base64url");const calculated=createHmac("sha256",requestStateSecret(secret)).update(body).digest();if(observed.byteLength!==calculated.byteLength||!timingSafeEqual(observed,calculated)){throw new PmMcpProtocolError("Invalid MCP requestState signature",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"})}let decoded;try{decoded=JSON.parse(Buffer.from(body,"base64url").toString("utf8"))}catch{decoded=null}const payload=parseMcpRequestStatePayload(decoded);const{expiresAt,method,parameterDigest,principal}=payload;if(expiresAt<(expected.nowMs??Date.now())){throw new PmMcpProtocolError("Expired MCP requestState",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState",expiredAt:expiresAt})}if(method!==expected.method||parameterDigest!==expected.parameterDigest||principal!==expected.principal){throw new PmMcpProtocolError("MCP requestState binding mismatch",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"})}return payload}function digestMcpRequestParameters(value){assertBoundedJson(value,MAX_INPUT_PAYLOAD_BYTES,"request parameters");return createHash("sha256").update(JSON.stringify(value)).digest("hex")}class PmMcpRequestStateReplayGuard{#consumed=new Set;#maximumEntries;constructor(maximumEntries=4096){if(!Number.isSafeInteger(maximumEntries)||maximumEntries<1){throw new PmMcpProtocolError("Invalid MCP replay guard capacity",PM_MCP_ERROR_CODES.invalidParams,{maximumEntries})}this.#maximumEntries=maximumEntries}consume(value){const digest=createHash("sha256").update(value).digest("hex");if(this.#consumed.has(digest)){throw new PmMcpProtocolError("MCP requestState replay detected",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"})}if(this.#consumed.size>=this.#maximumEntries){const oldest=this.#consumed.values().next().value;this.#consumed.delete(oldest)}this.#consumed.add(digest)}}function parseMcpCachePolicy(value){if(!Number.isSafeInteger(value.ttlMs)||value.ttlMs<0||value.cacheScope!=="public"&&value.cacheScope!=="private"){throw new PmMcpProtocolError("Invalid MCP cache policy",PM_MCP_ERROR_CODES.invalidParams,{ttlMs:value.ttlMs,cacheScope:value.cacheScope})}return{ttlMs:value.ttlMs,cacheScope:value.cacheScope}}function withMcpCachePolicy(payload,policy){return{...payload,...parseMcpCachePolicy(policy)}}function decodeJsonPointerToken(value){return value.replaceAll("~1","/").replaceAll("~0","~")}function resolveLocalJsonSchemaReference(root,reference){if(reference==="#")return root;if(!reference.startsWith("#/"))return void 0;let current=root;for(const token of reference.slice(2).split("/").map(decodeJsonPointerToken)){if(!isMcpRecord(current)&&!Array.isArray(current))return void 0;if(!Object.prototype.hasOwnProperty.call(current,token))return void 0;current=current[token]}return current}function resolveMcpJsonSchemaBounds(bounds){const maximumBytes=bounds.maxBytes??DEFAULT_SCHEMA_BOUNDS.maxBytes;const maximumDepth=bounds.maxDepth??DEFAULT_SCHEMA_BOUNDS.maxDepth;const maximumNodes=bounds.maxNodes??DEFAULT_SCHEMA_BOUNDS.maxNodes;if(!Number.isSafeInteger(maximumBytes)||maximumBytes<2){throw new PmMcpProtocolError("Invalid MCP JSON Schema work bounds",PM_MCP_ERROR_CODES.invalidParams)}if(!Number.isSafeInteger(maximumDepth)||maximumDepth<1){throw new PmMcpProtocolError("Invalid MCP JSON Schema work bounds",PM_MCP_ERROR_CODES.invalidParams)}if(!Number.isSafeInteger(maximumNodes)||maximumNodes<1){throw new PmMcpProtocolError("Invalid MCP JSON Schema work bounds",PM_MCP_ERROR_CODES.invalidParams)}return{maximumBytes,maximumDepth,maximumNodes}}function enqueueMcpJsonSchemaChildren(current,pending){const entries=Array.isArray(current.value)?current.value:isMcpRecord(current.value)?Object.values(current.value):[];for(const entry of entries){pending.push({value:entry,depth:current.depth+1})}}function assertMcpJsonSchemaReference(root,value){if(!isMcpRecord(value)||typeof value.$ref!=="string")return;const reference=value.$ref;if(reference.startsWith("#")&&resolveLocalJsonSchemaReference(root,reference)===void 0){throw new PmMcpProtocolError("MCP JSON Schema contains an unresolved local reference",PM_MCP_ERROR_CODES.invalidParams,{reference})}}function validateMcpJsonSchema(schema,bounds={}){const{maximumBytes,maximumDepth,maximumNodes}=resolveMcpJsonSchemaBounds(bounds);if(typeof schema!=="boolean"&&!isMcpRecord(schema)){throw new PmMcpProtocolError("Invalid MCP JSON Schema root",PM_MCP_ERROR_CODES.invalidParams,{expected:"object or boolean"})}assertBoundedJson(schema,maximumBytes,"JSON Schema");const pending=[{value:schema,depth:0}];let visited=0;while(pending.length>0){const current=pending.pop();visited+=1;if(visited>maximumNodes||current.depth>maximumDepth){throw new PmMcpProtocolError("MCP JSON Schema exceeds validation work bounds",PM_MCP_ERROR_CODES.invalidParams,{maximumDepth,maximumNodes})}assertMcpJsonSchemaReference(schema,current.value);enqueueMcpJsonSchemaChildren(current,pending)}return structuredClone(schema)}export{PM_MCP_INPUT_REQUEST_METHODS,PmMcpInputRequiredError,PmMcpRequestStateReplayGuard,buildMcpInputRequiredResult,digestMcpRequestParameters,openMcpRequestState,parseMcpCachePolicy,parseMcpInputRequests,parseMcpInputResponses,sealMcpRequestState,validateMcpJsonSchema,withMcpCachePolicy};
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]="15b81dd0-ef1a-58be-b6ee-5975b6778993")}catch{}})();import{createHash,createHmac,timingSafeEqual}from"node:crypto";import{PM_MCP_ERROR_CODES,PM_MCP_META_KEYS,PmMcpProtocolError,isMcpRecord}from"./protocol.js";const PM_MCP_INPUT_REQUEST_METHODS=["elicitation/create","roots/list","sampling/createMessage"];class PmMcpInputRequiredError extends Error{inputRequests;requestState;constructor(input){super("MCP operation requires additional input"),this.name="PmMcpInputRequiredError",this.inputRequests=input.inputRequests,this.requestState=input.requestState}}const INPUT_KEY_PATTERN=/^[a-zA-Z][a-zA-Z0-9_.-]{0,63}$/u,MAX_INPUT_REQUESTS=32,MAX_INPUT_PAYLOAD_BYTES=64*1024,MAX_REQUEST_STATE_BYTES=16*1024,DEFAULT_SCHEMA_BOUNDS={maxBytes:256*1024,maxDepth:32,maxNodes:4096};function inputCapability(method){return method==="elicitation/create"?"elicitation":method==="sampling/createMessage"?"sampling":"roots"}function assertBoundedJson(value,maximumBytes,field){let serialized;try{serialized=JSON.stringify(value)}catch{throw new PmMcpProtocolError(`Invalid ${field}: value is not JSON serializable`,PM_MCP_ERROR_CODES.invalidParams,{field})}if(Buffer.byteLength(serialized,"utf8")>maximumBytes)throw new PmMcpProtocolError(`Invalid ${field}: payload exceeds the protocol bound`,PM_MCP_ERROR_CODES.invalidParams,{field,maximumBytes})}function parseMcpInputRequests(value,requestContext){if(!isMcpRecord(value))throw new PmMcpProtocolError("Invalid MCP inputRequests",PM_MCP_ERROR_CODES.invalidParams,{field:"inputRequests",expected:"object"});const entries=Object.entries(value);if(entries.length===0||entries.length>MAX_INPUT_REQUESTS)throw new PmMcpProtocolError("Invalid MCP inputRequests count",PM_MCP_ERROR_CODES.invalidParams,{minimum:1,maximum:MAX_INPUT_REQUESTS,observed:entries.length});const parsed={};for(const[key,request]of entries){if(!INPUT_KEY_PATTERN.test(key)||!isMcpRecord(request))throw new PmMcpProtocolError("Invalid MCP input request entry",PM_MCP_ERROR_CODES.invalidParams,{field:`inputRequests.${key}`});const method=request.method;if(typeof method!="string"||!PM_MCP_INPUT_REQUEST_METHODS.includes(method))throw new PmMcpProtocolError("Unsupported MCP input request method",PM_MCP_ERROR_CODES.invalidParams,{field:`inputRequests.${key}.method`,method:method??null});const capability=inputCapability(method);if(!Object.prototype.hasOwnProperty.call(requestContext.clientCapabilities,capability))throw new PmMcpProtocolError("Missing required client capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:{[capability]:{}}});if(!isMcpRecord(request.params))throw new PmMcpProtocolError("Invalid MCP input request parameters",PM_MCP_ERROR_CODES.invalidParams,{field:`inputRequests.${key}.params`,expected:"object"});parsed[key]={method,params:structuredClone(request.params)}}return assertBoundedJson(parsed,MAX_INPUT_PAYLOAD_BYTES,"inputRequests"),parsed}function parseMcpInputResponses(value){if(!isMcpRecord(value))throw new PmMcpProtocolError("Invalid MCP inputResponses",PM_MCP_ERROR_CODES.invalidParams,{field:"inputResponses",expected:"object"});const entries=Object.entries(value);if(entries.length>MAX_INPUT_REQUESTS)throw new PmMcpProtocolError("Invalid MCP inputResponses count",PM_MCP_ERROR_CODES.invalidParams,{maximum:MAX_INPUT_REQUESTS,observed:entries.length});const parsed={};for(const[key,response]of entries){if(!INPUT_KEY_PATTERN.test(key)||!isMcpRecord(response))throw new PmMcpProtocolError("Invalid MCP input response entry",PM_MCP_ERROR_CODES.invalidParams,{field:`inputResponses.${key}`});parsed[key]=structuredClone(response)}return assertBoundedJson(parsed,MAX_INPUT_PAYLOAD_BYTES,"inputResponses"),parsed}function buildMcpInputRequiredResult(input){const requestState=input.requestState?.trim();if(requestState&&Buffer.byteLength(requestState,"utf8")>MAX_REQUEST_STATE_BYTES)throw new PmMcpProtocolError("Invalid MCP requestState: payload exceeds the protocol bound",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState",maximumBytes:MAX_REQUEST_STATE_BYTES});const inputRequests=input.inputRequests===void 0?void 0:parseMcpInputRequests(input.inputRequests,input.requestContext);if(inputRequests===void 0&&!requestState)throw new PmMcpProtocolError("InputRequiredResult requires inputRequests or requestState",PM_MCP_ERROR_CODES.invalidParams,{requiredAnyOf:["inputRequests","requestState"]});return{resultType:"input_required",...inputRequests?{inputRequests}:{},...requestState?{requestState}:{},_meta:{[PM_MCP_META_KEYS.serverInfo]:{...input.serverInfo}}}}function requestStateSecret(secret){const bytes=Buffer.from(secret);if(bytes.byteLength<32)throw new PmMcpProtocolError("MCP requestState signing key must contain at least 32 bytes",PM_MCP_ERROR_CODES.invalidParams,{minimumBytes:32});return bytes}function sealMcpRequestState(payload,secret){if(!Number.isSafeInteger(payload.expiresAt)||payload.expiresAt<=0||payload.method.trim().length===0||payload.parameterDigest.trim().length===0||payload.principal.trim().length===0)throw new PmMcpProtocolError("Invalid MCP requestState payload",PM_MCP_ERROR_CODES.invalidParams);const encoded=Buffer.from(JSON.stringify({version:1,...payload}),"utf8");if(encoded.byteLength>MAX_REQUEST_STATE_BYTES/2)throw new PmMcpProtocolError("MCP requestState payload exceeds the protocol bound",PM_MCP_ERROR_CODES.invalidParams,{maximumBytes:MAX_REQUEST_STATE_BYTES/2});const body=encoded.toString("base64url"),signature=createHmac("sha256",requestStateSecret(secret)).update(body).digest("base64url");return`${body}.${signature}`}function parseMcpRequestStatePayload(decoded){if(!isMcpRecord(decoded)||decoded.version!==1)throw new PmMcpProtocolError("Invalid MCP requestState payload",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"});const{expiresAt,method,parameterDigest,principal,state}=decoded;if(typeof expiresAt!="number"||!Number.isSafeInteger(expiresAt))throw new PmMcpProtocolError("Invalid MCP requestState payload",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"});if(typeof method!="string"||typeof parameterDigest!="string"||typeof principal!="string")throw new PmMcpProtocolError("Invalid MCP requestState payload",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"});return{expiresAt,method,parameterDigest,principal,state}}function openMcpRequestState(value,secret,expected){const[body,signature,extra]=value.split(".");if(!body||!signature||extra!==void 0)throw new PmMcpProtocolError("Invalid MCP requestState encoding",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"});const observed=Buffer.from(signature,"base64url"),calculated=createHmac("sha256",requestStateSecret(secret)).update(body).digest();if(observed.byteLength!==calculated.byteLength||!timingSafeEqual(observed,calculated))throw new PmMcpProtocolError("Invalid MCP requestState signature",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"});let decoded;try{decoded=JSON.parse(Buffer.from(body,"base64url").toString("utf8"))}catch{decoded=null}const payload=parseMcpRequestStatePayload(decoded),{expiresAt,method,parameterDigest,principal}=payload;if(expiresAt<(expected.nowMs??Date.now()))throw new PmMcpProtocolError("Expired MCP requestState",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState",expiredAt:expiresAt});if(method!==expected.method||parameterDigest!==expected.parameterDigest||principal!==expected.principal)throw new PmMcpProtocolError("MCP requestState binding mismatch",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"});return payload}function digestMcpRequestParameters(value){return assertBoundedJson(value,MAX_INPUT_PAYLOAD_BYTES,"request parameters"),createHash("sha256").update(JSON.stringify(value)).digest("hex")}class PmMcpRequestStateReplayGuard{#consumed=new Set;#maximumEntries;constructor(maximumEntries=4096){if(!Number.isSafeInteger(maximumEntries)||maximumEntries<1)throw new PmMcpProtocolError("Invalid MCP replay guard capacity",PM_MCP_ERROR_CODES.invalidParams,{maximumEntries});this.#maximumEntries=maximumEntries}consume(value){const digest=createHash("sha256").update(value).digest("hex");if(this.#consumed.has(digest))throw new PmMcpProtocolError("MCP requestState replay detected",PM_MCP_ERROR_CODES.invalidParams,{field:"requestState"});if(this.#consumed.size>=this.#maximumEntries){const oldest=this.#consumed.values().next().value;this.#consumed.delete(oldest)}this.#consumed.add(digest)}}function parseMcpCachePolicy(value){if(!Number.isSafeInteger(value.ttlMs)||value.ttlMs<0||value.cacheScope!=="public"&&value.cacheScope!=="private")throw new PmMcpProtocolError("Invalid MCP cache policy",PM_MCP_ERROR_CODES.invalidParams,{ttlMs:value.ttlMs,cacheScope:value.cacheScope});return{ttlMs:value.ttlMs,cacheScope:value.cacheScope}}function withMcpCachePolicy(payload,policy){return{...payload,...parseMcpCachePolicy(policy)}}function decodeJsonPointerToken(value){return value.replaceAll("~1","/").replaceAll("~0","~")}function resolveLocalJsonSchemaReference(root,reference){if(reference==="#")return root;if(!reference.startsWith("#/"))return;let current=root;for(const token of reference.slice(2).split("/").map(decodeJsonPointerToken)){if(!isMcpRecord(current)&&!Array.isArray(current)||!Object.prototype.hasOwnProperty.call(current,token))return;current=current[token]}return current}function resolveMcpJsonSchemaBounds(bounds){const maximumBytes=bounds.maxBytes??DEFAULT_SCHEMA_BOUNDS.maxBytes,maximumDepth=bounds.maxDepth??DEFAULT_SCHEMA_BOUNDS.maxDepth,maximumNodes=bounds.maxNodes??DEFAULT_SCHEMA_BOUNDS.maxNodes;if(!Number.isSafeInteger(maximumBytes)||maximumBytes<2)throw new PmMcpProtocolError("Invalid MCP JSON Schema work bounds",PM_MCP_ERROR_CODES.invalidParams);if(!Number.isSafeInteger(maximumDepth)||maximumDepth<1)throw new PmMcpProtocolError("Invalid MCP JSON Schema work bounds",PM_MCP_ERROR_CODES.invalidParams);if(!Number.isSafeInteger(maximumNodes)||maximumNodes<1)throw new PmMcpProtocolError("Invalid MCP JSON Schema work bounds",PM_MCP_ERROR_CODES.invalidParams);return{maximumBytes,maximumDepth,maximumNodes}}function enqueueMcpJsonSchemaChildren(current,pending){const entries=Array.isArray(current.value)?current.value:isMcpRecord(current.value)?Object.values(current.value):[];for(const entry of entries)pending.push({value:entry,depth:current.depth+1})}function assertMcpJsonSchemaReference(root,value){if(!isMcpRecord(value)||typeof value.$ref!="string")return;const reference=value.$ref;if(reference.startsWith("#")&&resolveLocalJsonSchemaReference(root,reference)===void 0)throw new PmMcpProtocolError("MCP JSON Schema contains an unresolved local reference",PM_MCP_ERROR_CODES.invalidParams,{reference})}function validateMcpJsonSchema(schema,bounds={}){const{maximumBytes,maximumDepth,maximumNodes}=resolveMcpJsonSchemaBounds(bounds);if(typeof schema!="boolean"&&!isMcpRecord(schema))throw new PmMcpProtocolError("Invalid MCP JSON Schema root",PM_MCP_ERROR_CODES.invalidParams,{expected:"object or boolean"});assertBoundedJson(schema,maximumBytes,"JSON Schema");const pending=[{value:schema,depth:0}];let visited=0;for(;pending.length>0;){const current=pending.pop();if(visited+=1,visited>maximumNodes||current.depth>maximumDepth)throw new PmMcpProtocolError("MCP JSON Schema exceeds validation work bounds",PM_MCP_ERROR_CODES.invalidParams,{maximumDepth,maximumNodes});assertMcpJsonSchemaReference(schema,current.value),enqueueMcpJsonSchemaChildren(current,pending)}return structuredClone(schema)}export{PM_MCP_INPUT_REQUEST_METHODS,PmMcpInputRequiredError,PmMcpRequestStateReplayGuard,buildMcpInputRequiredResult,digestMcpRequestParameters,openMcpRequestState,parseMcpCachePolicy,parseMcpInputRequests,parseMcpInputResponses,sealMcpRequestState,validateMcpJsonSchema,withMcpCachePolicy};
2
2
  //# sourceMappingURL=interactions.js.map
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="08485124-a2f1-5bb5-9316-533a3f7888bc")}catch(e2){}})();const PM_MCP_PROTOCOL_VERSION="2026-07-28";const PM_MCP_LEGACY_PROTOCOL_VERSIONS=["2025-11-25","2025-06-18"];const PM_MCP_SUPPORTED_PROTOCOL_VERSIONS=[PM_MCP_PROTOCOL_VERSION];const PM_MCP_ERROR_CODES={headerMismatch:-32020,missingRequiredClientCapability:-32021,unsupportedProtocolVersion:-32022,invalidParams:-32602};const PM_MCP_META_KEYS={clientCapabilities:"io.modelcontextprotocol/clientCapabilities",clientInfo:"io.modelcontextprotocol/clientInfo",logLevel:"io.modelcontextprotocol/logLevel",protocolVersion:"io.modelcontextprotocol/protocolVersion",serverInfo:"io.modelcontextprotocol/serverInfo"};const PM_MCP_LOG_LEVELS=["debug","info","notice","warning","error","critical","alert","emergency"];class PmMcpProtocolError extends Error{code;data;constructor(message,code,data={}){super(message);this.name="PmMcpProtocolError";this.code=code;this.data=data}}function isMcpRecord(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function parseMcpImplementation(value){if(value===void 0)return void 0;if(!isMcpRecord(value)){throw new PmMcpProtocolError("Invalid MCP clientInfo metadata",PM_MCP_ERROR_CODES.invalidParams,{field:PM_MCP_META_KEYS.clientInfo,expected:"object"})}const name=typeof value.name==="string"?value.name.trim():"";const version=typeof value.version==="string"?value.version.trim():"";if(name.length===0||version.length===0){throw new PmMcpProtocolError("Invalid MCP clientInfo metadata",PM_MCP_ERROR_CODES.invalidParams,{field:PM_MCP_META_KEYS.clientInfo,required:["name","version"]})}const parsed={name:name.slice(0,128),version:version.slice(0,128)};if(typeof value.description==="string"&&value.description.trim()){parsed.description=value.description.trim().slice(0,1024)}if(typeof value.websiteUrl==="string"&&value.websiteUrl.trim()){parsed.websiteUrl=value.websiteUrl.trim().slice(0,2048)}return parsed}function parseMcpLogLevel(value){if(value===void 0)return void 0;if(typeof value!=="string"||!PM_MCP_LOG_LEVELS.includes(value)){throw new PmMcpProtocolError("Invalid MCP logLevel metadata",PM_MCP_ERROR_CODES.invalidParams,{field:PM_MCP_META_KEYS.logLevel,allowed:[...PM_MCP_LOG_LEVELS]})}return value}function resolveMcpRequestContext(params){const meta=isMcpRecord(params)?params._meta:void 0;if(!isMcpRecord(meta)){throw new PmMcpProtocolError("Missing required MCP request metadata",PM_MCP_ERROR_CODES.invalidParams,{required:[PM_MCP_META_KEYS.protocolVersion,PM_MCP_META_KEYS.clientCapabilities]})}const requested=meta[PM_MCP_META_KEYS.protocolVersion];if(typeof requested!=="string"||!PM_MCP_SUPPORTED_PROTOCOL_VERSIONS.includes(requested)){throw new PmMcpProtocolError("Unsupported protocol version",PM_MCP_ERROR_CODES.unsupportedProtocolVersion,{supported:[...PM_MCP_SUPPORTED_PROTOCOL_VERSIONS],requested:typeof requested==="string"?requested:null})}const clientCapabilities=meta[PM_MCP_META_KEYS.clientCapabilities];if(!isMcpRecord(clientCapabilities)){throw new PmMcpProtocolError("Invalid MCP client capabilities metadata",PM_MCP_ERROR_CODES.invalidParams,{field:PM_MCP_META_KEYS.clientCapabilities,expected:"object"})}const clientInfo=parseMcpImplementation(meta[PM_MCP_META_KEYS.clientInfo]);const logLevel=parseMcpLogLevel(meta[PM_MCP_META_KEYS.logLevel]);return{protocolVersion:PM_MCP_PROTOCOL_VERSION,clientCapabilities,...clientInfo?{clientInfo}:{},...logLevel?{logLevel}:{}}}function assertMcpProtocolHeader(requestContext,headerValue){if(headerValue!==requestContext.protocolVersion){throw new PmMcpProtocolError("MCP protocol header does not match request metadata",PM_MCP_ERROR_CODES.headerMismatch,{header:headerValue??null,metadata:requestContext.protocolVersion})}}function assertMcpClientCapabilities(requestContext,requiredCapabilities){const missing=requiredCapabilities.filter(capability=>!Object.prototype.hasOwnProperty.call(requestContext.clientCapabilities,capability));if(missing.length>0){throw new PmMcpProtocolError("Missing required client capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:Object.fromEntries(missing.map(capability=>[capability,{}]))})}}function hasMcpClientExtension(requestContext,extension){const extensions=requestContext.clientCapabilities.extensions;return isMcpRecord(extensions)&&isMcpRecord(extensions[extension])}function attachMcpServerInfo(payload,serverInfo){const payloadMeta=isMcpRecord(payload._meta)?payload._meta:{};return{...payload,_meta:{...payloadMeta,[PM_MCP_META_KEYS.serverInfo]:{...serverInfo}}}}function buildMcpCompleteResult(payload,serverInfo){return attachMcpServerInfo({...payload,resultType:"complete"},serverInfo)}function buildMcpDiscoverResult(input){const ttlMs=input.ttlMs??6e4;if(!Number.isFinite(ttlMs)||ttlMs<0){throw new PmMcpProtocolError("Invalid MCP discovery cache TTL",PM_MCP_ERROR_CODES.invalidParams,{ttlMs})}return buildMcpCompleteResult({supportedVersions:[...PM_MCP_SUPPORTED_PROTOCOL_VERSIONS],capabilities:structuredClone(input.capabilities),ttlMs,cacheScope:"public",...input.instructions?{instructions:input.instructions}:{}},input.serverInfo)}function interpretMcpResultType(result,era){if(isMcpRecord(result)&&typeof result.resultType==="string"){return result.resultType}if(era==="legacy")return"complete";throw new PmMcpProtocolError("Modern MCP result is missing resultType",PM_MCP_ERROR_CODES.invalidParams,{required:"resultType"})}export{PM_MCP_ERROR_CODES,PM_MCP_LEGACY_PROTOCOL_VERSIONS,PM_MCP_LOG_LEVELS,PM_MCP_META_KEYS,PM_MCP_PROTOCOL_VERSION,PM_MCP_SUPPORTED_PROTOCOL_VERSIONS,PmMcpProtocolError,assertMcpClientCapabilities,assertMcpProtocolHeader,attachMcpServerInfo,buildMcpCompleteResult,buildMcpDiscoverResult,hasMcpClientExtension,interpretMcpResultType,isMcpRecord,parseMcpImplementation,resolveMcpRequestContext};
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]="8f11e0bf-4115-55a8-bd39-c360f43cdc09")}catch{}})();const PM_MCP_PROTOCOL_VERSION="2026-07-28",PM_MCP_LEGACY_PROTOCOL_VERSIONS=["2025-11-25","2025-06-18"],PM_MCP_SUPPORTED_PROTOCOL_VERSIONS=[PM_MCP_PROTOCOL_VERSION],PM_MCP_ERROR_CODES={headerMismatch:-32020,missingRequiredClientCapability:-32021,unsupportedProtocolVersion:-32022,invalidParams:-32602},PM_MCP_META_KEYS={clientCapabilities:"io.modelcontextprotocol/clientCapabilities",clientInfo:"io.modelcontextprotocol/clientInfo",logLevel:"io.modelcontextprotocol/logLevel",protocolVersion:"io.modelcontextprotocol/protocolVersion",serverInfo:"io.modelcontextprotocol/serverInfo"},PM_MCP_LOG_LEVELS=["debug","info","notice","warning","error","critical","alert","emergency"];class PmMcpProtocolError extends Error{code;data;constructor(message,code,data={}){super(message),this.name="PmMcpProtocolError",this.code=code,this.data=data}}function isMcpRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function parseMcpImplementation(value){if(value===void 0)return;if(!isMcpRecord(value))throw new PmMcpProtocolError("Invalid MCP clientInfo metadata",PM_MCP_ERROR_CODES.invalidParams,{field:PM_MCP_META_KEYS.clientInfo,expected:"object"});const name=typeof value.name=="string"?value.name.trim():"",version=typeof value.version=="string"?value.version.trim():"";if(name.length===0||version.length===0)throw new PmMcpProtocolError("Invalid MCP clientInfo metadata",PM_MCP_ERROR_CODES.invalidParams,{field:PM_MCP_META_KEYS.clientInfo,required:["name","version"]});const parsed={name:name.slice(0,128),version:version.slice(0,128)};return typeof value.description=="string"&&value.description.trim()&&(parsed.description=value.description.trim().slice(0,1024)),typeof value.websiteUrl=="string"&&value.websiteUrl.trim()&&(parsed.websiteUrl=value.websiteUrl.trim().slice(0,2048)),parsed}function parseMcpLogLevel(value){if(value!==void 0){if(typeof value!="string"||!PM_MCP_LOG_LEVELS.includes(value))throw new PmMcpProtocolError("Invalid MCP logLevel metadata",PM_MCP_ERROR_CODES.invalidParams,{field:PM_MCP_META_KEYS.logLevel,allowed:[...PM_MCP_LOG_LEVELS]});return value}}function resolveMcpRequestContext(params){const meta=isMcpRecord(params)?params._meta:void 0;if(!isMcpRecord(meta))throw new PmMcpProtocolError("Missing required MCP request metadata",PM_MCP_ERROR_CODES.invalidParams,{required:[PM_MCP_META_KEYS.protocolVersion,PM_MCP_META_KEYS.clientCapabilities]});const requested=meta[PM_MCP_META_KEYS.protocolVersion];if(typeof requested!="string"||!PM_MCP_SUPPORTED_PROTOCOL_VERSIONS.includes(requested))throw new PmMcpProtocolError("Unsupported protocol version",PM_MCP_ERROR_CODES.unsupportedProtocolVersion,{supported:[...PM_MCP_SUPPORTED_PROTOCOL_VERSIONS],requested:typeof requested=="string"?requested:null});const clientCapabilities=meta[PM_MCP_META_KEYS.clientCapabilities];if(!isMcpRecord(clientCapabilities))throw new PmMcpProtocolError("Invalid MCP client capabilities metadata",PM_MCP_ERROR_CODES.invalidParams,{field:PM_MCP_META_KEYS.clientCapabilities,expected:"object"});const clientInfo=parseMcpImplementation(meta[PM_MCP_META_KEYS.clientInfo]),logLevel=parseMcpLogLevel(meta[PM_MCP_META_KEYS.logLevel]);return{protocolVersion:PM_MCP_PROTOCOL_VERSION,clientCapabilities,...clientInfo?{clientInfo}:{},...logLevel?{logLevel}:{}}}function assertMcpProtocolHeader(requestContext,headerValue){if(headerValue!==requestContext.protocolVersion)throw new PmMcpProtocolError("MCP protocol header does not match request metadata",PM_MCP_ERROR_CODES.headerMismatch,{header:headerValue??null,metadata:requestContext.protocolVersion})}function assertMcpClientCapabilities(requestContext,requiredCapabilities){const missing=requiredCapabilities.filter(capability=>!Object.prototype.hasOwnProperty.call(requestContext.clientCapabilities,capability));if(missing.length>0)throw new PmMcpProtocolError("Missing required client capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:Object.fromEntries(missing.map(capability=>[capability,{}]))})}function hasMcpClientExtension(requestContext,extension){const extensions=requestContext.clientCapabilities.extensions;return isMcpRecord(extensions)&&isMcpRecord(extensions[extension])}function attachMcpServerInfo(payload,serverInfo){const payloadMeta=isMcpRecord(payload._meta)?payload._meta:{};return{...payload,_meta:{...payloadMeta,[PM_MCP_META_KEYS.serverInfo]:{...serverInfo}}}}function buildMcpCompleteResult(payload,serverInfo){return attachMcpServerInfo({...payload,resultType:"complete"},serverInfo)}function buildMcpDiscoverResult(input){const ttlMs=input.ttlMs??6e4;if(!Number.isFinite(ttlMs)||ttlMs<0)throw new PmMcpProtocolError("Invalid MCP discovery cache TTL",PM_MCP_ERROR_CODES.invalidParams,{ttlMs});return buildMcpCompleteResult({supportedVersions:[...PM_MCP_SUPPORTED_PROTOCOL_VERSIONS],capabilities:structuredClone(input.capabilities),ttlMs,cacheScope:"public",...input.instructions?{instructions:input.instructions}:{}},input.serverInfo)}function interpretMcpResultType(result,era){if(isMcpRecord(result)&&typeof result.resultType=="string")return result.resultType;if(era==="legacy")return"complete";throw new PmMcpProtocolError("Modern MCP result is missing resultType",PM_MCP_ERROR_CODES.invalidParams,{required:"resultType"})}export{PM_MCP_ERROR_CODES,PM_MCP_LEGACY_PROTOCOL_VERSIONS,PM_MCP_LOG_LEVELS,PM_MCP_META_KEYS,PM_MCP_PROTOCOL_VERSION,PM_MCP_SUPPORTED_PROTOCOL_VERSIONS,PmMcpProtocolError,assertMcpClientCapabilities,assertMcpProtocolHeader,attachMcpServerInfo,buildMcpCompleteResult,buildMcpDiscoverResult,hasMcpClientExtension,interpretMcpResultType,isMcpRecord,parseMcpImplementation,resolveMcpRequestContext};
2
2
  //# sourceMappingURL=protocol.js.map
@@ -1,2 +1,4 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6bfbe073-3869-5451-9d65-499960a28af9")}catch(e2){}})();import{createHash}from"node:crypto";import{lstat,readdir,readFile}from"node:fs/promises";import path from"node:path";import{parseDocument}from"yaml";import{isFileAbsentError}from"../../core/fs/fs-utils.js";import{PM_MCP_ERROR_CODES,PM_MCP_PROTOCOL_VERSION,PmMcpProtocolError,isMcpRecord}from"./protocol.js";const PM_MCP_SKILLS_EXTENSION="io.modelcontextprotocol/skills";const PM_MCP_SKILLS_DRAFT_REVISION="SEP-2640@a3e147ca2710f68214247aecc729731ee1ae8d03";const PM_MCP_SKILLS_SERVER_CAPABILITY=Object.freeze({revision:PM_MCP_SKILLS_DRAFT_REVISION,status:"draft",directoryRead:true});function assertPmMcpSkillsCapability(context,directoryRead=false){const extensions=context.clientCapabilities.extensions;const declaration=isMcpRecord(extensions)?extensions[PM_MCP_SKILLS_EXTENSION]:void 0;if(!isMcpRecord(declaration)||declaration.revision!==PM_MCP_SKILLS_DRAFT_REVISION||directoryRead&&declaration.directoryRead!==true){throw new PmMcpProtocolError("Missing or incompatible Skills over MCP draft capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:{extensions:{[PM_MCP_SKILLS_EXTENSION]:PM_MCP_SKILLS_SERVER_CAPABILITY}}})}}const PM_MCP_SKILL_LIMITS=Object.freeze({maxFilesPerSkill:512,maxFileBytes:16*1024*1024,maxSkillBytes:16*1024*1024,defaultPageSize:20,maxPageSize:100});const MAX_MCP_SKILLS_PER_ORIGIN=100;const MAX_MCP_SKILL_ORIGIN_BYTES=32*1024*1024;const SKILL_NAME_PATTERN=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;const SKILL_PAGE_SIZES=new Set(Array.from({length:PM_MCP_SKILL_LIMITS.maxPageSize},(_,index)=>index+1));function skillError(message,data){throw new PmMcpProtocolError(message,-32602,data)}function skillFileMimeType(name,bytes){try{new TextDecoder("utf-8",{fatal:true}).decode(bytes);return name.endsWith(".md")?"text/markdown":"text/plain"}catch{return"application/octet-stream"}}function parseSkillFrontmatter(content,source){const match=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(content);if(!match)skillError(`Skill ${source} is missing YAML frontmatter.`);const document=parseDocument(match[1],{prettyErrors:false,strict:true,uniqueKeys:true});if(document.errors.length>0){skillError(`Skill ${source} has invalid YAML frontmatter.`,{errors:document.errors.map(error=>error.message)})}let value;try{value=document.toJS({maxAliasCount:0})}catch(error){skillError(`Skill ${source} has unsupported YAML aliases.`,{error:String(error)})}if(typeof value!=="object"||value===null||Array.isArray(value)){skillError(`Skill ${source} frontmatter must be an object.`)}return value}async function readBoundedSkillFile(filePath,relative,size,budget){if(size>PM_MCP_SKILL_LIMITS.maxFileBytes){skillError(`Skill resource exceeds the per-file limit: ${relative}.`)}budget.files+=1;if(budget.files>PM_MCP_SKILL_LIMITS.maxFilesPerSkill){skillError(`Skill exceeds ${PM_MCP_SKILL_LIMITS.maxFilesPerSkill} files.`)}budget.skillBytes+=size;if(budget.skillBytes>PM_MCP_SKILL_LIMITS.maxSkillBytes){skillError(`Skill exceeds the aggregate byte limit: ${relative}.`)}budget.originBytes.value+=size;if(budget.originBytes.value>MAX_MCP_SKILL_ORIGIN_BYTES){skillError(`Skill origin exceeds the aggregate byte limit: ${relative}.`)}return readFile(filePath)}async function collectSkillFiles(root,relative,budget){const directory=path.join(root,relative);const entries=await readdir(directory,{withFileTypes:true});const files=[];for(const entry of entries.sort((left,right)=>left.name.localeCompare(right.name))){const childRelative=path.posix.join(relative.split(path.sep).join("/"),entry.name);const childPath=path.join(root,...childRelative.split("/"));const stats=await lstat(childPath);if(stats.isSymbolicLink()){skillError(`Skill resource must not be a symbolic link: ${childRelative}.`)}if(stats.isDirectory()){files.push(...await collectSkillFiles(root,childRelative,budget))}else if(stats.isFile()){files.push({relative:childRelative,bytes:await readBoundedSkillFile(childPath,childRelative,stats.size,budget)})}else{skillError(`Skill resource must be a regular file or directory: ${childRelative}.`)}}return files}async function loadSkillOrigin(skillsRoot,origin,packageVersion){const skills=new Map;let entries;try{entries=await readdir(skillsRoot,{withFileTypes:true})}catch(error){if(isFileAbsentError(error)){return skills}throw error}const skillEntries=entries.filter(entry=>entry.isDirectory()&&SKILL_NAME_PATTERN.test(entry.name)).sort((left,right)=>left.name.localeCompare(right.name));if(skillEntries.length>MAX_MCP_SKILLS_PER_ORIGIN){skillError(`Skill origin exceeds ${MAX_MCP_SKILLS_PER_ORIGIN} directories.`)}const originBytes={value:0};for(const entry of skillEntries){const files=await collectSkillFiles(path.join(skillsRoot,entry.name),"",{files:0,skillBytes:0,originBytes});const totalBytes=files.reduce((sum,file)=>sum+file.bytes.byteLength,0);const main=files.find(file=>file.relative==="SKILL.md");if(!main)continue;const frontmatter=parseSkillFrontmatter(main.bytes.toString("utf8"),entry.name);if(frontmatter.name!==entry.name){skillError(`Skill directory ${entry.name} must match frontmatter name.`,{actual:frontmatter.name??null,expected:entry.name})}if(typeof frontmatter.description!=="string"||frontmatter.description.trim().length===0){skillError(`Skill ${entry.name} requires a non-empty frontmatter description.`,{required:["description"]})}const resources=files.map(file=>({uri:`skill://${entry.name}/${file.relative}`,digest:`sha256:${createHash("sha256").update(file.bytes).digest("hex")}`,size:file.bytes.byteLength}));const fingerprint=createHash("sha256").update(resources.map(resource=>`${resource.uri}:${resource.digest}`).join("\n")).digest("hex");skills.set(entry.name,{uri:`skill://${entry.name}/SKILL.md`,frontmatter,resources,_meta:{contractVersion:1,extensionRevision:PM_MCP_SKILLS_DRAFT_REVISION,origin,packageVersion,protocolVersion:PM_MCP_PROTOCOL_VERSION,trust:"untrusted",estimatedTokens:Math.ceil(totalBytes/4)},files:new Map(files.map(file=>[file.relative,file.bytes])),fingerprint})}return skills}function projectSkill(skill){const{files:_files,fingerprint:_fingerprint,...descriptor}=skill;return descriptor}class PmMcpSkillRegistry{#skills;#fingerprint;constructor(skills){this.#skills=skills;this.#fingerprint=createHash("sha256").update([...skills.entries()].sort(([left],[right])=>left.localeCompare(right)).map(([name,skill])=>`${name}:${skill.fingerprint}`).join("\n")).digest("hex").slice(0,16)}#decodeCursor(cursor,scope){if(!cursor)return 0;try{const parsed=JSON.parse(Buffer.from(cursor,"base64url").toString("utf8"));if(typeof parsed!=="object"||parsed===null||!("fingerprint"in parsed)||parsed.fingerprint!==this.#fingerprint||!("scope"in parsed)||parsed.scope!==scope||!("offset"in parsed)||!Number.isInteger(parsed.offset)||Number(parsed.offset)<0){skillError("Skill cursor is invalid or stale.")}return Number(parsed.offset)}catch(error){if(error instanceof PmMcpProtocolError)throw error;return skillError("Skill cursor is invalid or stale.")}}#encodeCursor(offset,scope){return Buffer.from(JSON.stringify({fingerprint:this.#fingerprint,offset,scope})).toString("base64url")}static async load(options){const packaged=await loadSkillOrigin(path.join(options.packageRoot,".agents","skills"),"package",options.packageVersion);if(options.workspaceRoot){const packageSkillsRoot=path.resolve(options.packageRoot,".agents","skills");const workspaceSkillsRoot=path.resolve(options.workspaceRoot,".agents","skills");if(workspaceSkillsRoot!==packageSkillsRoot){const overrides=await loadSkillOrigin(workspaceSkillsRoot,"workspace",options.packageVersion);for(const[name,skill]of overrides)packaged.set(name,skill)}}return new PmMcpSkillRegistry(packaged)}list(options={}){const limit=options.limit??PM_MCP_SKILL_LIMITS.defaultPageSize;if(!SKILL_PAGE_SIZES.has(limit)){skillError(`Skill list limit must be an integer from 1 to ${PM_MCP_SKILL_LIMITS.maxPageSize}.`)}const offset=this.#decodeCursor(options.cursor,"skills/list");const ordered=[...this.#skills.values()].sort((left,right)=>left.uri.localeCompare(right.uri));const page=ordered.slice(offset,offset+limit);const nextOffset=offset+page.length;const hasMore=nextOffset<ordered.length;return{skills:page.map(projectSkill),hasMore,...hasMore?{nextCursor:this.#encodeCursor(nextOffset,"skills/list")}:{}}}get(uri){const match=/^skill:\/\/([a-z0-9]+(?:-[a-z0-9]+)*)\/SKILL\.md$/u.exec(uri);const skill=match?this.#skills.get(match[1]):void 0;if(!skill)skillError(`Unknown pm MCP skill: ${uri}.`,{field:"uri"});return projectSkill(skill)}read(uri){const match=/^skill:\/\/([a-z0-9]+(?:-[a-z0-9]+)*)\/(.+)$/u.exec(uri);const skill=match?this.#skills.get(match[1]):void 0;const relative=match?.[2]??"";const bytes=skill&&relative?skill.files.get(relative):void 0;const resource=skill?.resources.find(candidate=>candidate.uri===uri);if(!skill||!bytes||!resource){skillError(`Unknown pm MCP skill resource: ${uri}.`,{field:"uri"})}const metadata={digest:resource.digest,origin:skill._meta.origin,trust:"untrusted"};const mimeType=skillFileMimeType(relative,bytes);if(mimeType!=="application/octet-stream"){return{contents:[{uri,mimeType,text:bytes.toString("utf8"),_meta:metadata}]}}return{contents:[{uri,mimeType,blob:bytes.toString("base64"),_meta:metadata}]}}readDirectory(uri,options={}){const match=/^skill:\/\/([a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(.+))?$/u.exec(uri);const skill=match?this.#skills.get(match[1]):void 0;if(!skill)skillError(`Unknown pm MCP skill directory: ${uri}.`,{field:"uri"});const directory=(match?.[2]??"").replace(/\/$/u,"");const prefix=directory.length>0?`${directory}/`:"";const base=`skill://${match[1]}`;const children=new Map;for(const resource of skill.resources){const relative=resource.uri.slice(`${base}/`.length);if(!relative.startsWith(prefix))continue;const remainder=relative.slice(prefix.length);const[name,...descendants]=remainder.split("/");const childUri=`${base}/${prefix}${name}`;const childBytes=skill.files.get(`${prefix}${name}`);children.set(name,{uri:childUri,name,mimeType:descendants.length>0?"inode/directory":skillFileMimeType(name,childBytes)})}if(directory.length>0&&children.size===0){skillError(`Unknown pm MCP skill directory: ${uri}.`,{field:"uri"})}const limit=options.limit??PM_MCP_SKILL_LIMITS.maxPageSize;if(!SKILL_PAGE_SIZES.has(limit)){skillError(`Skill directory limit must be an integer from 1 to ${PM_MCP_SKILL_LIMITS.maxPageSize}.`)}const offset=this.#decodeCursor(options.cursor,uri);const ordered=[...children.values()].sort((left,right)=>left.uri.localeCompare(right.uri));const resources=ordered.slice(offset,offset+limit);const nextOffset=offset+resources.length;const hasMore=nextOffset<ordered.length;return{resources,hasMore,...hasMore?{nextCursor:this.#encodeCursor(nextOffset,uri)}:{}}}}export{PM_MCP_SKILLS_DRAFT_REVISION,PM_MCP_SKILLS_EXTENSION,PM_MCP_SKILLS_SERVER_CAPABILITY,PM_MCP_SKILL_LIMITS,PmMcpSkillRegistry,assertPmMcpSkillsCapability};
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]="eafd8bc3-0da1-5220-8fb1-6967eecdb6bf")}catch{}})();import{createHash}from"node:crypto";import{lstat,readdir,readFile}from"node:fs/promises";import path from"node:path";import{parseDocument}from"yaml";import{isFileAbsentError}from"../../core/fs/fs-utils.js";import{PM_MCP_ERROR_CODES,PM_MCP_PROTOCOL_VERSION,PmMcpProtocolError,isMcpRecord}from"./protocol.js";const PM_MCP_SKILLS_EXTENSION="io.modelcontextprotocol/skills",PM_MCP_SKILLS_DRAFT_REVISION="SEP-2640@a3e147ca2710f68214247aecc729731ee1ae8d03",PM_MCP_SKILLS_SERVER_CAPABILITY=Object.freeze({revision:PM_MCP_SKILLS_DRAFT_REVISION,status:"draft",directoryRead:!0});function assertPmMcpSkillsCapability(context,directoryRead=!1){const extensions=context.clientCapabilities.extensions,declaration=isMcpRecord(extensions)?extensions[PM_MCP_SKILLS_EXTENSION]:void 0;if(!isMcpRecord(declaration)||declaration.revision!==PM_MCP_SKILLS_DRAFT_REVISION||directoryRead&&declaration.directoryRead!==!0)throw new PmMcpProtocolError("Missing or incompatible Skills over MCP draft capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:{extensions:{[PM_MCP_SKILLS_EXTENSION]:PM_MCP_SKILLS_SERVER_CAPABILITY}}})}const PM_MCP_SKILL_LIMITS=Object.freeze({maxFilesPerSkill:512,maxFileBytes:16*1024*1024,maxSkillBytes:16*1024*1024,defaultPageSize:20,maxPageSize:100}),MAX_MCP_SKILLS_PER_ORIGIN=100,MAX_MCP_SKILL_ORIGIN_BYTES=32*1024*1024,SKILL_NAME_PATTERN=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u,SKILL_PAGE_SIZES=new Set(Array.from({length:PM_MCP_SKILL_LIMITS.maxPageSize},(_,index)=>index+1));function skillError(message,data){throw new PmMcpProtocolError(message,-32602,data)}function skillFileMimeType(name,bytes){try{return new TextDecoder("utf-8",{fatal:!0}).decode(bytes),name.endsWith(".md")?"text/markdown":"text/plain"}catch{return"application/octet-stream"}}function parseSkillFrontmatter(content,source){const match=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(content);match||skillError(`Skill ${source} is missing YAML frontmatter.`);const document=parseDocument(match[1],{prettyErrors:!1,strict:!0,uniqueKeys:!0});document.errors.length>0&&skillError(`Skill ${source} has invalid YAML frontmatter.`,{errors:document.errors.map(error=>error.message)});let value;try{value=document.toJS({maxAliasCount:0})}catch(error){skillError(`Skill ${source} has unsupported YAML aliases.`,{error:String(error)})}return(typeof value!="object"||value===null||Array.isArray(value))&&skillError(`Skill ${source} frontmatter must be an object.`),value}async function readBoundedSkillFile(filePath,relative,size,budget){return size>PM_MCP_SKILL_LIMITS.maxFileBytes&&skillError(`Skill resource exceeds the per-file limit: ${relative}.`),budget.files+=1,budget.files>PM_MCP_SKILL_LIMITS.maxFilesPerSkill&&skillError(`Skill exceeds ${PM_MCP_SKILL_LIMITS.maxFilesPerSkill} files.`),budget.skillBytes+=size,budget.skillBytes>PM_MCP_SKILL_LIMITS.maxSkillBytes&&skillError(`Skill exceeds the aggregate byte limit: ${relative}.`),budget.originBytes.value+=size,budget.originBytes.value>MAX_MCP_SKILL_ORIGIN_BYTES&&skillError(`Skill origin exceeds the aggregate byte limit: ${relative}.`),readFile(filePath)}async function collectSkillFiles(root,relative,budget){const directory=path.join(root,relative),entries=await readdir(directory,{withFileTypes:!0}),files=[];for(const entry of entries.sort((left,right)=>left.name.localeCompare(right.name))){const childRelative=path.posix.join(relative.split(path.sep).join("/"),entry.name),childPath=path.join(root,...childRelative.split("/")),stats=await lstat(childPath);stats.isSymbolicLink()&&skillError(`Skill resource must not be a symbolic link: ${childRelative}.`),stats.isDirectory()?files.push(...await collectSkillFiles(root,childRelative,budget)):stats.isFile()?files.push({relative:childRelative,bytes:await readBoundedSkillFile(childPath,childRelative,stats.size,budget)}):skillError(`Skill resource must be a regular file or directory: ${childRelative}.`)}return files}async function loadSkillOrigin(skillsRoot,origin,packageVersion){const skills=new Map;let entries;try{entries=await readdir(skillsRoot,{withFileTypes:!0})}catch(error){if(isFileAbsentError(error))return skills;throw error}const skillEntries=entries.filter(entry=>entry.isDirectory()&&SKILL_NAME_PATTERN.test(entry.name)).sort((left,right)=>left.name.localeCompare(right.name));skillEntries.length>MAX_MCP_SKILLS_PER_ORIGIN&&skillError(`Skill origin exceeds ${MAX_MCP_SKILLS_PER_ORIGIN} directories.`);const originBytes={value:0};for(const entry of skillEntries){const files=await collectSkillFiles(path.join(skillsRoot,entry.name),"",{files:0,skillBytes:0,originBytes}),totalBytes=files.reduce((sum,file)=>sum+file.bytes.byteLength,0),main=files.find(file=>file.relative==="SKILL.md");if(!main)continue;const frontmatter=parseSkillFrontmatter(main.bytes.toString("utf8"),entry.name);frontmatter.name!==entry.name&&skillError(`Skill directory ${entry.name} must match frontmatter name.`,{actual:frontmatter.name??null,expected:entry.name}),(typeof frontmatter.description!="string"||frontmatter.description.trim().length===0)&&skillError(`Skill ${entry.name} requires a non-empty frontmatter description.`,{required:["description"]});const resources=files.map(file=>({uri:`skill://${entry.name}/${file.relative}`,digest:`sha256:${createHash("sha256").update(file.bytes).digest("hex")}`,size:file.bytes.byteLength})),fingerprint=createHash("sha256").update(resources.map(resource=>`${resource.uri}:${resource.digest}`).join(`
2
+ `)).digest("hex");skills.set(entry.name,{uri:`skill://${entry.name}/SKILL.md`,frontmatter,resources,_meta:{contractVersion:1,extensionRevision:PM_MCP_SKILLS_DRAFT_REVISION,origin,packageVersion,protocolVersion:PM_MCP_PROTOCOL_VERSION,trust:"untrusted",estimatedTokens:Math.ceil(totalBytes/4)},files:new Map(files.map(file=>[file.relative,file.bytes])),fingerprint})}return skills}function projectSkill(skill){const{files:_files,fingerprint:_fingerprint,...descriptor}=skill;return descriptor}class PmMcpSkillRegistry{#skills;#fingerprint;constructor(skills){this.#skills=skills,this.#fingerprint=createHash("sha256").update([...skills.entries()].sort(([left],[right])=>left.localeCompare(right)).map(([name,skill])=>`${name}:${skill.fingerprint}`).join(`
3
+ `)).digest("hex").slice(0,16)}#decodeCursor(cursor,scope){if(!cursor)return 0;try{const parsed=JSON.parse(Buffer.from(cursor,"base64url").toString("utf8"));return(typeof parsed!="object"||parsed===null||!("fingerprint"in parsed)||parsed.fingerprint!==this.#fingerprint||!("scope"in parsed)||parsed.scope!==scope||!("offset"in parsed)||!Number.isInteger(parsed.offset)||Number(parsed.offset)<0)&&skillError("Skill cursor is invalid or stale."),Number(parsed.offset)}catch(error){if(error instanceof PmMcpProtocolError)throw error;return skillError("Skill cursor is invalid or stale.")}}#encodeCursor(offset,scope){return Buffer.from(JSON.stringify({fingerprint:this.#fingerprint,offset,scope})).toString("base64url")}static async load(options){const packaged=await loadSkillOrigin(path.join(options.packageRoot,".agents","skills"),"package",options.packageVersion);if(options.workspaceRoot){const packageSkillsRoot=path.resolve(options.packageRoot,".agents","skills"),workspaceSkillsRoot=path.resolve(options.workspaceRoot,".agents","skills");if(workspaceSkillsRoot!==packageSkillsRoot){const overrides=await loadSkillOrigin(workspaceSkillsRoot,"workspace",options.packageVersion);for(const[name,skill]of overrides)packaged.set(name,skill)}}return new PmMcpSkillRegistry(packaged)}list(options={}){const limit=options.limit??PM_MCP_SKILL_LIMITS.defaultPageSize;SKILL_PAGE_SIZES.has(limit)||skillError(`Skill list limit must be an integer from 1 to ${PM_MCP_SKILL_LIMITS.maxPageSize}.`);const offset=this.#decodeCursor(options.cursor,"skills/list"),ordered=[...this.#skills.values()].sort((left,right)=>left.uri.localeCompare(right.uri)),page=ordered.slice(offset,offset+limit),nextOffset=offset+page.length,hasMore=nextOffset<ordered.length;return{skills:page.map(projectSkill),hasMore,...hasMore?{nextCursor:this.#encodeCursor(nextOffset,"skills/list")}:{}}}get(uri){const match=/^skill:\/\/([a-z0-9]+(?:-[a-z0-9]+)*)\/SKILL\.md$/u.exec(uri),skill=match?this.#skills.get(match[1]):void 0;return skill||skillError(`Unknown pm MCP skill: ${uri}.`,{field:"uri"}),projectSkill(skill)}read(uri){const match=/^skill:\/\/([a-z0-9]+(?:-[a-z0-9]+)*)\/(.+)$/u.exec(uri),skill=match?this.#skills.get(match[1]):void 0,relative=match?.[2]??"",bytes=skill&&relative?skill.files.get(relative):void 0,resource=skill?.resources.find(candidate=>candidate.uri===uri);(!skill||!bytes||!resource)&&skillError(`Unknown pm MCP skill resource: ${uri}.`,{field:"uri"});const metadata={digest:resource.digest,origin:skill._meta.origin,trust:"untrusted"},mimeType=skillFileMimeType(relative,bytes);return mimeType!=="application/octet-stream"?{contents:[{uri,mimeType,text:bytes.toString("utf8"),_meta:metadata}]}:{contents:[{uri,mimeType,blob:bytes.toString("base64"),_meta:metadata}]}}readDirectory(uri,options={}){const match=/^skill:\/\/([a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(.+))?$/u.exec(uri),skill=match?this.#skills.get(match[1]):void 0;skill||skillError(`Unknown pm MCP skill directory: ${uri}.`,{field:"uri"});const directory=(match?.[2]??"").replace(/\/$/u,""),prefix=directory.length>0?`${directory}/`:"",base=`skill://${match[1]}`,children=new Map;for(const resource of skill.resources){const relative=resource.uri.slice(`${base}/`.length);if(!relative.startsWith(prefix))continue;const remainder=relative.slice(prefix.length),[name,...descendants]=remainder.split("/"),childUri=`${base}/${prefix}${name}`,childBytes=skill.files.get(`${prefix}${name}`);children.set(name,{uri:childUri,name,mimeType:descendants.length>0?"inode/directory":skillFileMimeType(name,childBytes)})}directory.length>0&&children.size===0&&skillError(`Unknown pm MCP skill directory: ${uri}.`,{field:"uri"});const limit=options.limit??PM_MCP_SKILL_LIMITS.maxPageSize;SKILL_PAGE_SIZES.has(limit)||skillError(`Skill directory limit must be an integer from 1 to ${PM_MCP_SKILL_LIMITS.maxPageSize}.`);const offset=this.#decodeCursor(options.cursor,uri),ordered=[...children.values()].sort((left,right)=>left.uri.localeCompare(right.uri)),resources=ordered.slice(offset,offset+limit),nextOffset=offset+resources.length,hasMore=nextOffset<ordered.length;return{resources,hasMore,...hasMore?{nextCursor:this.#encodeCursor(nextOffset,uri)}:{}}}}export{PM_MCP_SKILLS_DRAFT_REVISION,PM_MCP_SKILLS_EXTENSION,PM_MCP_SKILLS_SERVER_CAPABILITY,PM_MCP_SKILL_LIMITS,PmMcpSkillRegistry,assertPmMcpSkillsCapability};
2
4
  //# sourceMappingURL=skills.js.map
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f87864d3-e499-57f7-b1e3-4ea3f30b7725")}catch(e2){}})();import{PM_MCP_ERROR_CODES,PmMcpProtocolError,attachMcpServerInfo,isMcpRecord}from"./protocol.js";const PM_MCP_SUBSCRIPTION_ID_META_KEY="io.modelcontextprotocol/subscriptionId";const MAX_RESOURCE_SUBSCRIPTIONS=256;const MAX_RESOURCE_URI_BYTES=2048;const MCP_SUBSCRIPTION_WRITE_TIMEOUT_MS=5e3;function writeSubscriptionNotification(sink,notification){return new Promise((resolve,reject)=>{const timer=setTimeout(()=>reject(new Error("MCP subscription sink write timed out")),MCP_SUBSCRIPTION_WRITE_TIMEOUT_MS);timer.unref();Promise.resolve().then(()=>sink(notification)).then(()=>{clearTimeout(timer);resolve()},error=>{clearTimeout(timer);reject(error instanceof Error?error:new Error(String(error)))})})}function validateOptionalBoolean(value,field){if(value===void 0)return void 0;if(typeof value!=="boolean"){throw new PmMcpProtocolError("Invalid MCP subscription filter",PM_MCP_ERROR_CODES.invalidParams,{field:`notifications.${field}`,expected:"boolean"})}return value||void 0}function parseMcpSubscriptionFilter(value){if(!isMcpRecord(value)){throw new PmMcpProtocolError("Invalid MCP subscription filter",PM_MCP_ERROR_CODES.invalidParams,{field:"notifications",expected:"object"})}const toolsListChanged=validateOptionalBoolean(value.toolsListChanged,"toolsListChanged");const promptsListChanged=validateOptionalBoolean(value.promptsListChanged,"promptsListChanged");const resourcesListChanged=validateOptionalBoolean(value.resourcesListChanged,"resourcesListChanged");let resourceSubscriptions;if(value.resourceSubscriptions!==void 0){if(!Array.isArray(value.resourceSubscriptions)||value.resourceSubscriptions.length>MAX_RESOURCE_SUBSCRIPTIONS){throw new PmMcpProtocolError("Invalid MCP resource subscriptions",PM_MCP_ERROR_CODES.invalidParams,{field:"notifications.resourceSubscriptions",maximum:MAX_RESOURCE_SUBSCRIPTIONS})}const unique=new Set;for(const entry of value.resourceSubscriptions){if(typeof entry!=="string"||entry.trim().length===0||Buffer.byteLength(entry,"utf8")>MAX_RESOURCE_URI_BYTES){throw new PmMcpProtocolError("Invalid MCP resource subscription URI",PM_MCP_ERROR_CODES.invalidParams,{field:"notifications.resourceSubscriptions",maximumBytes:MAX_RESOURCE_URI_BYTES})}unique.add(entry)}if(unique.size>0)resourceSubscriptions=[...unique].sort()}return{...toolsListChanged?{toolsListChanged}:{},...promptsListChanged?{promptsListChanged}:{},...resourcesListChanged?{resourcesListChanged}:{},...resourceSubscriptions?{resourceSubscriptions}:{}}}function resolveMcpAcknowledgedSubscriptionFilter(requested,capabilities){return{...requested.toolsListChanged&&capabilities.tools?.listChanged?{toolsListChanged:true}:{},...requested.promptsListChanged&&capabilities.prompts?.listChanged?{promptsListChanged:true}:{},...requested.resourcesListChanged&&capabilities.resources?.listChanged?{resourcesListChanged:true}:{},...requested.resourceSubscriptions&&capabilities.resources?.subscribe?{resourceSubscriptions:[...requested.resourceSubscriptions]}:{}}}class PmMcpSubscriptionRegistry{#capabilities;#records=new Map;#serverInfo;constructor(input){this.#capabilities=structuredClone(input.capabilities);this.#serverInfo={...input.serverInfo}}get size(){return this.#records.size}async open(input){if(this.#records.has(input.id)){throw new PmMcpProtocolError("MCP subscription id is already active",PM_MCP_ERROR_CODES.invalidParams,{subscriptionId:input.id})}const filter=resolveMcpAcknowledgedSubscriptionFilter(parseMcpSubscriptionFilter(input.notifications),this.#capabilities);const record={filter,sink:input.sink,writeQueue:Promise.resolve()};this.#records.set(input.id,record);try{await this.#deliver(input.id,record,{jsonrpc:"2.0",method:"notifications/subscriptions/acknowledged",params:{_meta:{[PM_MCP_SUBSCRIPTION_ID_META_KEY]:input.id},notifications:structuredClone(filter)}},true)}catch(error){this.#records.delete(input.id);throw error}return structuredClone(filter)}async emitListChanged(family){const field=`${family}ListChanged`;const method=`notifications/${family}/list_changed`;const writes=[];for(const[id,record]of this.#records){if(record.filter[field]!==true)continue;writes.push(this.#deliver(id,record,{jsonrpc:"2.0",method,params:{_meta:{[PM_MCP_SUBSCRIPTION_ID_META_KEY]:id}}}))}return(await Promise.all(writes)).filter(Boolean).length}async emitResourceUpdated(uri){const writes=[];for(const[id,record]of this.#records){if(!record.filter.resourceSubscriptions?.includes(uri))continue;writes.push(this.#deliver(id,record,{jsonrpc:"2.0",method:"notifications/resources/updated",params:{_meta:{[PM_MCP_SUBSCRIPTION_ID_META_KEY]:id},uri}}))}return(await Promise.all(writes)).filter(Boolean).length}async#deliver(id,record,notification,propagateFailure=false){const pending=record.writeQueue.then(async()=>{if(this.#records.get(id)!==record)return false;try{await writeSubscriptionNotification(record.sink,notification);return true}catch(error){if(this.#records.get(id)===record)this.#records.delete(id);if(propagateFailure)throw error;return false}});record.writeQueue=pending.then(()=>void 0,()=>void 0);return pending}close(id){if(!this.#records.delete(id))return void 0;return{...attachMcpServerInfo({resultType:"complete",_meta:{[PM_MCP_SUBSCRIPTION_ID_META_KEY]:id}},this.#serverInfo)}}closeAll(){const closed=[];for(const id of this.#records.keys()){const result=this.close(id);closed.push({id,result})}return closed}}export{PM_MCP_SUBSCRIPTION_ID_META_KEY,PmMcpSubscriptionRegistry,parseMcpSubscriptionFilter,resolveMcpAcknowledgedSubscriptionFilter};
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]="15cbe26a-5716-5e8c-8700-eb36a1a056d6")}catch{}})();import{PM_MCP_ERROR_CODES,PmMcpProtocolError,attachMcpServerInfo,isMcpRecord}from"./protocol.js";const PM_MCP_SUBSCRIPTION_ID_META_KEY="io.modelcontextprotocol/subscriptionId",MAX_RESOURCE_SUBSCRIPTIONS=256,MAX_RESOURCE_URI_BYTES=2048,MCP_SUBSCRIPTION_WRITE_TIMEOUT_MS=5e3;function writeSubscriptionNotification(sink,notification){return new Promise((resolve,reject)=>{const timer=setTimeout(()=>reject(new Error("MCP subscription sink write timed out")),MCP_SUBSCRIPTION_WRITE_TIMEOUT_MS);timer.unref(),Promise.resolve().then(()=>sink(notification)).then(()=>{clearTimeout(timer),resolve()},error=>{clearTimeout(timer),reject(error instanceof Error?error:new Error(String(error)))})})}function validateOptionalBoolean(value,field){if(value!==void 0){if(typeof value!="boolean")throw new PmMcpProtocolError("Invalid MCP subscription filter",PM_MCP_ERROR_CODES.invalidParams,{field:`notifications.${field}`,expected:"boolean"});return value||void 0}}function parseMcpSubscriptionFilter(value){if(!isMcpRecord(value))throw new PmMcpProtocolError("Invalid MCP subscription filter",PM_MCP_ERROR_CODES.invalidParams,{field:"notifications",expected:"object"});const toolsListChanged=validateOptionalBoolean(value.toolsListChanged,"toolsListChanged"),promptsListChanged=validateOptionalBoolean(value.promptsListChanged,"promptsListChanged"),resourcesListChanged=validateOptionalBoolean(value.resourcesListChanged,"resourcesListChanged");let resourceSubscriptions;if(value.resourceSubscriptions!==void 0){if(!Array.isArray(value.resourceSubscriptions)||value.resourceSubscriptions.length>MAX_RESOURCE_SUBSCRIPTIONS)throw new PmMcpProtocolError("Invalid MCP resource subscriptions",PM_MCP_ERROR_CODES.invalidParams,{field:"notifications.resourceSubscriptions",maximum:MAX_RESOURCE_SUBSCRIPTIONS});const unique=new Set;for(const entry of value.resourceSubscriptions){if(typeof entry!="string"||entry.trim().length===0||Buffer.byteLength(entry,"utf8")>MAX_RESOURCE_URI_BYTES)throw new PmMcpProtocolError("Invalid MCP resource subscription URI",PM_MCP_ERROR_CODES.invalidParams,{field:"notifications.resourceSubscriptions",maximumBytes:MAX_RESOURCE_URI_BYTES});unique.add(entry)}unique.size>0&&(resourceSubscriptions=[...unique].sort())}return{...toolsListChanged?{toolsListChanged}:{},...promptsListChanged?{promptsListChanged}:{},...resourcesListChanged?{resourcesListChanged}:{},...resourceSubscriptions?{resourceSubscriptions}:{}}}function resolveMcpAcknowledgedSubscriptionFilter(requested,capabilities){return{...requested.toolsListChanged&&capabilities.tools?.listChanged?{toolsListChanged:!0}:{},...requested.promptsListChanged&&capabilities.prompts?.listChanged?{promptsListChanged:!0}:{},...requested.resourcesListChanged&&capabilities.resources?.listChanged?{resourcesListChanged:!0}:{},...requested.resourceSubscriptions&&capabilities.resources?.subscribe?{resourceSubscriptions:[...requested.resourceSubscriptions]}:{}}}class PmMcpSubscriptionRegistry{#capabilities;#records=new Map;#serverInfo;constructor(input){this.#capabilities=structuredClone(input.capabilities),this.#serverInfo={...input.serverInfo}}get size(){return this.#records.size}async open(input){if(this.#records.has(input.id))throw new PmMcpProtocolError("MCP subscription id is already active",PM_MCP_ERROR_CODES.invalidParams,{subscriptionId:input.id});const filter=resolveMcpAcknowledgedSubscriptionFilter(parseMcpSubscriptionFilter(input.notifications),this.#capabilities),record={filter,sink:input.sink,writeQueue:Promise.resolve()};this.#records.set(input.id,record);try{await this.#deliver(input.id,record,{jsonrpc:"2.0",method:"notifications/subscriptions/acknowledged",params:{_meta:{[PM_MCP_SUBSCRIPTION_ID_META_KEY]:input.id},notifications:structuredClone(filter)}},!0)}catch(error){throw this.#records.delete(input.id),error}return structuredClone(filter)}async emitListChanged(family){const field=`${family}ListChanged`,method=`notifications/${family}/list_changed`,writes=[];for(const[id,record]of this.#records)record.filter[field]===!0&&writes.push(this.#deliver(id,record,{jsonrpc:"2.0",method,params:{_meta:{[PM_MCP_SUBSCRIPTION_ID_META_KEY]:id}}}));return(await Promise.all(writes)).filter(Boolean).length}async emitResourceUpdated(uri){const writes=[];for(const[id,record]of this.#records)record.filter.resourceSubscriptions?.includes(uri)&&writes.push(this.#deliver(id,record,{jsonrpc:"2.0",method:"notifications/resources/updated",params:{_meta:{[PM_MCP_SUBSCRIPTION_ID_META_KEY]:id},uri}}));return(await Promise.all(writes)).filter(Boolean).length}async#deliver(id,record,notification,propagateFailure=!1){const pending=record.writeQueue.then(async()=>{if(this.#records.get(id)!==record)return!1;try{return await writeSubscriptionNotification(record.sink,notification),!0}catch(error){if(this.#records.get(id)===record&&this.#records.delete(id),propagateFailure)throw error;return!1}});return record.writeQueue=pending.then(()=>{},()=>{}),pending}close(id){if(this.#records.delete(id))return{...attachMcpServerInfo({resultType:"complete",_meta:{[PM_MCP_SUBSCRIPTION_ID_META_KEY]:id}},this.#serverInfo)}}closeAll(){const closed=[];for(const id of this.#records.keys()){const result=this.close(id);closed.push({id,result})}return closed}}export{PM_MCP_SUBSCRIPTION_ID_META_KEY,PmMcpSubscriptionRegistry,parseMcpSubscriptionFilter,resolveMcpAcknowledgedSubscriptionFilter};
2
2
  //# sourceMappingURL=subscriptions.js.map
@@ -1,3 +1,3 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7f5b3ba6-07cf-5317-8f62-63e84f561232")}catch(e2){}})();import{randomUUID}from"node:crypto";import{readFile}from"node:fs/promises";import path from"node:path";import{acquireLock,isFileMissingError,writeFileAtomic}from"../runtime-primitives.js";import{PM_MCP_ERROR_CODES,PmMcpProtocolError,isMcpRecord}from"./protocol.js";import{parseMcpInputRequests,parseMcpInputResponses}from"./interactions.js";const PM_MCP_TASKS_EXTENSION="io.modelcontextprotocol/tasks";const PM_MCP_TASK_STATUSES=["working","input_required","completed","failed","cancelled"];const TASK_ID_PATTERN=/^mcp-task-[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;const DEFAULT_TASK_TTL_MS=60*60*1e3;const DEFAULT_TASK_POLL_INTERVAL_MS=1e3;const MAX_STATUS_MESSAGE_LENGTH=1024;const TASK_LOCK_TTL_SECONDS=30;const TASK_LOCK_WAIT_MS=2e3;function taskProtocolError(message){return new PmMcpProtocolError(message,PM_MCP_ERROR_CODES.invalidParams,{code:"mcp_task_not_found_or_not_authorized"})}function validateTaskId(taskId){const normalized=taskId.trim();if(!TASK_ID_PATTERN.test(normalized)){throw taskProtocolError("Unknown MCP task")}return normalized}function parseTimestamp(value,field){if(typeof value!=="string"||!Number.isFinite(Date.parse(value))){throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams,{field})}return value}function parseTaskError(value){if(!isMcpRecord(value)||typeof value.code!=="number"||!Number.isFinite(value.code)||typeof value.message!=="string"){throw new PmMcpProtocolError("Corrupt MCP task error",PM_MCP_ERROR_CODES.invalidParams)}return{code:value.code,message:value.message.slice(0,MAX_STATUS_MESSAGE_LENGTH),...isMcpRecord(value.data)?{data:structuredClone(value.data)}:{}}}function parseTaskStatus(value){if(!PM_MCP_TASK_STATUSES.includes(value)){throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams)}return value}function parseTaskPrincipal(value){if(typeof value!=="string"||value.length===0){throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams)}return value}function parseTaskWorkerPid(value){if(typeof value!=="number"||!Number.isSafeInteger(value)||value<1){throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams)}return value}function parseTaskTtl(value){if(value!==null&&(typeof value!=="number"||!Number.isSafeInteger(value)||value<0)){throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams)}return value}function parseTaskPollInterval(value){if(value===void 0)return void 0;if(typeof value!=="number"||!Number.isSafeInteger(value)||value<0){throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams)}return value}function parseConsumedInputKeys(value){if(!Array.isArray(value)||value.some(entry=>typeof entry!=="string")){throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams)}return[...value]}function parseStoredTask(value){if(!isMcpRecord(value)||value.version!==1){throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams)}const taskId=typeof value.taskId==="string"?validateTaskId(value.taskId):"";const status=parseTaskStatus(value.status);const principal=parseTaskPrincipal(value.principal);const workerPid=parseTaskWorkerPid(value.workerPid);const ttlMs=parseTaskTtl(value.ttlMs);const pollIntervalMs=parseTaskPollInterval(value.pollIntervalMs);const parsed={version:1,taskId,status,principal,workerPid,createdAt:parseTimestamp(value.createdAt,"createdAt"),lastUpdatedAt:parseTimestamp(value.lastUpdatedAt,"lastUpdatedAt"),ttlMs,consumedInputKeys:parseConsumedInputKeys(value.consumedInputKeys),...typeof value.statusMessage==="string"?{statusMessage:value.statusMessage.slice(0,MAX_STATUS_MESSAGE_LENGTH)}:{},...typeof pollIntervalMs==="number"?{pollIntervalMs}:{}};if(isMcpRecord(value.inputRequests)){parsed.inputRequests=structuredClone(value.inputRequests)}if(isMcpRecord(value.inputResponses)){parsed.inputResponses=structuredClone(value.inputResponses)}if(isMcpRecord(value.result))parsed.result=structuredClone(value.result);if(value.error!==void 0)parsed.error=parseTaskError(value.error);if(parsed.status==="input_required"&&!parsed.inputRequests||parsed.status==="completed"&&!parsed.result||parsed.status==="failed"&&!parsed.error){throw new PmMcpProtocolError("Corrupt MCP task status payload",PM_MCP_ERROR_CODES.invalidParams,{status:parsed.status})}return parsed}function publicTask(record){const base={taskId:record.taskId,status:record.status,createdAt:record.createdAt,lastUpdatedAt:record.lastUpdatedAt,ttlMs:record.ttlMs,...record.statusMessage?{statusMessage:record.statusMessage}:{},...record.pollIntervalMs===void 0?{}:{pollIntervalMs:record.pollIntervalMs}};if(record.status==="input_required"){return{...base,status:"input_required",inputRequests:structuredClone(record.inputRequests)}}if(record.status==="completed"){return{...base,status:"completed",result:structuredClone(record.result)}}if(record.status==="failed"){return{...base,status:"failed",error:structuredClone(record.error)}}return record.status==="cancelled"?{...base,status:"cancelled"}:{...base,status:"working"}}function isTerminalTask(status){return status==="completed"||status==="failed"||status==="cancelled"}function isProcessAlive(pid){try{process.kill(pid,0);return true}catch(error){return!(typeof error==="object"&&error!==null&&"code"in error&&error.code==="ESRCH")}}class PmMcpTaskStore{#pmRoot;#owner;#now;#taskIdFactory;#workerPid;constructor(options){this.#pmRoot=path.resolve(options.pmRoot);this.#owner=options.owner?.trim()||"pm-mcp";this.#now=options.now??(()=>new Date);this.#taskIdFactory=options.taskIdFactory??(()=>`mcp-task-${randomUUID()}`);this.#workerPid=options.workerPid??process.pid}#taskPath(taskId){return path.join(this.#pmRoot,"runtime","mcp-tasks","records",`${validateTaskId(taskId)}.json`)}async#read(taskId){try{return parseStoredTask(JSON.parse(await readFile(this.#taskPath(taskId),"utf8")))}catch(error){if(isFileMissingError(error)||error instanceof SyntaxError){throw taskProtocolError("Unknown MCP task")}throw error}}async#write(record){await writeFileAtomic(this.#taskPath(record.taskId),`${JSON.stringify(record,null,2)}
2
- `)}async#mutate(taskId,principal,mutation){const normalizedId=validateTaskId(taskId);const release=await acquireLock(this.#pmRoot,normalizedId,TASK_LOCK_TTL_SECONDS,this.#owner,false,false,TASK_LOCK_WAIT_MS);try{const current=await this.#read(normalizedId);if(current.principal!==principal)throw taskProtocolError("Unknown MCP task");const next=mutation(current);await this.#write(next);return next}finally{await release()}}async create(input){const taskId=validateTaskId(this.#taskIdFactory());const principal=input.principal.trim();const ttlMs=input.ttlMs===void 0?DEFAULT_TASK_TTL_MS:input.ttlMs;const pollIntervalMs=input.pollIntervalMs??DEFAULT_TASK_POLL_INTERVAL_MS;if(principal.length===0||ttlMs!==null&&(!Number.isSafeInteger(ttlMs)||ttlMs<0)||!Number.isSafeInteger(pollIntervalMs)||pollIntervalMs<0){throw new PmMcpProtocolError("Invalid MCP task creation options",PM_MCP_ERROR_CODES.invalidParams)}const timestamp=this.#now().toISOString();const record={version:1,taskId,status:"working",createdAt:timestamp,lastUpdatedAt:timestamp,ttlMs,pollIntervalMs,principal,workerPid:this.#workerPid,consumedInputKeys:[],...input.statusMessage?.trim()?{statusMessage:input.statusMessage.trim().slice(0,MAX_STATUS_MESSAGE_LENGTH)}:{}};await this.#write(record);return{...publicTask(record),resultType:"task"}}async get(taskId,principal){return publicTask(await this.#mutate(taskId,principal,record=>{if(isTerminalTask(record.status))return record;const nowMs=this.#now().getTime();const expired=record.ttlMs!==null&&Date.parse(record.createdAt)+record.ttlMs<=nowMs;const unavailableWorker=record.workerPid!==this.#workerPid&&!isProcessAlive(record.workerPid);if(!expired&&!unavailableWorker)return record;return{...record,status:"failed",statusMessage:expired?"Task retention expired before completion.":"Task worker ended before recording a terminal result.",lastUpdatedAt:this.#now().toISOString(),error:{code:-32603,message:expired?"MCP task expired":"MCP task worker unavailable after restart",data:{recoverable:false,createNewTask:true}},inputRequests:void 0}}))}async requireInput(input){const requests=parseMcpInputRequests(input.inputRequests,input.requestContext);return publicTask(await this.#mutate(input.taskId,input.principal,record=>{if(isTerminalTask(record.status))return record;const reused=Object.keys(requests).filter(key=>record.consumedInputKeys.includes(key));if(reused.length>0){throw new PmMcpProtocolError("MCP task input request keys must be unique for the task lifetime",PM_MCP_ERROR_CODES.invalidParams,{reused})}return{...record,status:"input_required",statusMessage:input.statusMessage?.trim().slice(0,MAX_STATUS_MESSAGE_LENGTH),lastUpdatedAt:this.#now().toISOString(),inputRequests:requests}}))}async update(taskId,principal,inputResponses){const responses=parseMcpInputResponses(inputResponses);const acceptedKeys=[];let remainingKeys=[];await this.#mutate(taskId,principal,record=>{if(record.status!=="input_required"||!record.inputRequests){return record}const outstanding={...record.inputRequests};const accepted=record.inputResponses?{...record.inputResponses}:{};for(const[key,response]of Object.entries(responses)){if(!Object.prototype.hasOwnProperty.call(outstanding,key))continue;accepted[key]=response;delete outstanding[key];acceptedKeys.push(key)}remainingKeys=Object.keys(outstanding).sort();if(acceptedKeys.length===0)return record;return{...record,status:remainingKeys.length===0?"working":"input_required",lastUpdatedAt:this.#now().toISOString(),inputRequests:remainingKeys.length===0?void 0:outstanding,inputResponses:accepted,consumedInputKeys:[...new Set([...record.consumedInputKeys,...acceptedKeys])].sort()}});return{acceptedKeys:acceptedKeys.sort(),remainingKeys}}async takeInputResponses(taskId,principal){let responses={};await this.#mutate(taskId,principal,record=>{responses=structuredClone(record.inputResponses??{});if(Object.keys(responses).length===0)return record;return{...record,inputResponses:void 0}});return responses}async complete(taskId,principal,result){return publicTask(await this.#mutate(taskId,principal,record=>isTerminalTask(record.status)?record:{...record,status:"completed",statusMessage:"Task completed.",lastUpdatedAt:this.#now().toISOString(),result:structuredClone(result),inputRequests:void 0,error:void 0}))}async fail(taskId,principal,error){const boundedError=parseTaskError(error);return publicTask(await this.#mutate(taskId,principal,record=>isTerminalTask(record.status)?record:{...record,status:"failed",statusMessage:boundedError.message,lastUpdatedAt:this.#now().toISOString(),error:boundedError,inputRequests:void 0,result:void 0}))}async cancel(taskId,principal){return publicTask(await this.#mutate(taskId,principal,record=>isTerminalTask(record.status)?record:{...record,status:"cancelled",statusMessage:"Task cancelled by the client.",lastUpdatedAt:this.#now().toISOString(),inputRequests:void 0,result:void 0,error:void 0}))}}function createMcpTaskStore(options){return new PmMcpTaskStore(options)}export{PM_MCP_TASKS_EXTENSION,PM_MCP_TASK_STATUSES,PmMcpTaskStore,createMcpTaskStore};
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]="f3e94896-b2a0-561c-902b-71c28ddde2a1")}catch{}})();import{randomUUID}from"node:crypto";import{readFile}from"node:fs/promises";import path from"node:path";import{acquireLock,isFileMissingError,writeFileAtomic}from"../runtime-primitives.js";import{PM_MCP_ERROR_CODES,PmMcpProtocolError,isMcpRecord}from"./protocol.js";import{parseMcpInputRequests,parseMcpInputResponses}from"./interactions.js";const PM_MCP_TASKS_EXTENSION="io.modelcontextprotocol/tasks",PM_MCP_TASK_STATUSES=["working","input_required","completed","failed","cancelled"],TASK_ID_PATTERN=/^mcp-task-[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu,DEFAULT_TASK_TTL_MS=3600*1e3,DEFAULT_TASK_POLL_INTERVAL_MS=1e3,MAX_STATUS_MESSAGE_LENGTH=1024,TASK_LOCK_TTL_SECONDS=30,TASK_LOCK_WAIT_MS=2e3;function taskProtocolError(message){return new PmMcpProtocolError(message,PM_MCP_ERROR_CODES.invalidParams,{code:"mcp_task_not_found_or_not_authorized"})}function validateTaskId(taskId){const normalized=taskId.trim();if(!TASK_ID_PATTERN.test(normalized))throw taskProtocolError("Unknown MCP task");return normalized}function parseTimestamp(value,field){if(typeof value!="string"||!Number.isFinite(Date.parse(value)))throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams,{field});return value}function parseTaskError(value){if(!isMcpRecord(value)||typeof value.code!="number"||!Number.isFinite(value.code)||typeof value.message!="string")throw new PmMcpProtocolError("Corrupt MCP task error",PM_MCP_ERROR_CODES.invalidParams);return{code:value.code,message:value.message.slice(0,MAX_STATUS_MESSAGE_LENGTH),...isMcpRecord(value.data)?{data:structuredClone(value.data)}:{}}}function parseTaskStatus(value){if(!PM_MCP_TASK_STATUSES.includes(value))throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams);return value}function parseTaskPrincipal(value){if(typeof value!="string"||value.length===0)throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams);return value}function parseTaskWorkerPid(value){if(typeof value!="number"||!Number.isSafeInteger(value)||value<1)throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams);return value}function parseTaskTtl(value){if(value!==null&&(typeof value!="number"||!Number.isSafeInteger(value)||value<0))throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams);return value}function parseTaskPollInterval(value){if(value!==void 0){if(typeof value!="number"||!Number.isSafeInteger(value)||value<0)throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams);return value}}function parseConsumedInputKeys(value){if(!Array.isArray(value)||value.some(entry=>typeof entry!="string"))throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams);return[...value]}function parseStoredTask(value){if(!isMcpRecord(value)||value.version!==1)throw new PmMcpProtocolError("Corrupt MCP task record",PM_MCP_ERROR_CODES.invalidParams);const taskId=typeof value.taskId=="string"?validateTaskId(value.taskId):"",status=parseTaskStatus(value.status),principal=parseTaskPrincipal(value.principal),workerPid=parseTaskWorkerPid(value.workerPid),ttlMs=parseTaskTtl(value.ttlMs),pollIntervalMs=parseTaskPollInterval(value.pollIntervalMs),parsed={version:1,taskId,status,principal,workerPid,createdAt:parseTimestamp(value.createdAt,"createdAt"),lastUpdatedAt:parseTimestamp(value.lastUpdatedAt,"lastUpdatedAt"),ttlMs,consumedInputKeys:parseConsumedInputKeys(value.consumedInputKeys),...typeof value.statusMessage=="string"?{statusMessage:value.statusMessage.slice(0,MAX_STATUS_MESSAGE_LENGTH)}:{},...typeof pollIntervalMs=="number"?{pollIntervalMs}:{}};if(isMcpRecord(value.inputRequests)&&(parsed.inputRequests=structuredClone(value.inputRequests)),isMcpRecord(value.inputResponses)&&(parsed.inputResponses=structuredClone(value.inputResponses)),isMcpRecord(value.result)&&(parsed.result=structuredClone(value.result)),value.error!==void 0&&(parsed.error=parseTaskError(value.error)),parsed.status==="input_required"&&!parsed.inputRequests||parsed.status==="completed"&&!parsed.result||parsed.status==="failed"&&!parsed.error)throw new PmMcpProtocolError("Corrupt MCP task status payload",PM_MCP_ERROR_CODES.invalidParams,{status:parsed.status});return parsed}function publicTask(record){const base={taskId:record.taskId,status:record.status,createdAt:record.createdAt,lastUpdatedAt:record.lastUpdatedAt,ttlMs:record.ttlMs,...record.statusMessage?{statusMessage:record.statusMessage}:{},...record.pollIntervalMs===void 0?{}:{pollIntervalMs:record.pollIntervalMs}};return record.status==="input_required"?{...base,status:"input_required",inputRequests:structuredClone(record.inputRequests)}:record.status==="completed"?{...base,status:"completed",result:structuredClone(record.result)}:record.status==="failed"?{...base,status:"failed",error:structuredClone(record.error)}:record.status==="cancelled"?{...base,status:"cancelled"}:{...base,status:"working"}}function isTerminalTask(status){return status==="completed"||status==="failed"||status==="cancelled"}function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch(error){return!(typeof error=="object"&&error!==null&&"code"in error&&error.code==="ESRCH")}}class PmMcpTaskStore{#pmRoot;#owner;#now;#taskIdFactory;#workerPid;constructor(options){this.#pmRoot=path.resolve(options.pmRoot),this.#owner=options.owner?.trim()||"pm-mcp",this.#now=options.now??(()=>new Date),this.#taskIdFactory=options.taskIdFactory??(()=>`mcp-task-${randomUUID()}`),this.#workerPid=options.workerPid??process.pid}#taskPath(taskId){return path.join(this.#pmRoot,"runtime","mcp-tasks","records",`${validateTaskId(taskId)}.json`)}async#read(taskId){try{return parseStoredTask(JSON.parse(await readFile(this.#taskPath(taskId),"utf8")))}catch(error){throw isFileMissingError(error)||error instanceof SyntaxError?taskProtocolError("Unknown MCP task"):error}}async#write(record){await writeFileAtomic(this.#taskPath(record.taskId),`${JSON.stringify(record,null,2)}
2
+ `)}async#mutate(taskId,principal,mutation){const normalizedId=validateTaskId(taskId),release=await acquireLock(this.#pmRoot,normalizedId,TASK_LOCK_TTL_SECONDS,this.#owner,!1,!1,TASK_LOCK_WAIT_MS);try{const current=await this.#read(normalizedId);if(current.principal!==principal)throw taskProtocolError("Unknown MCP task");const next=mutation(current);return await this.#write(next),next}finally{await release()}}async create(input){const taskId=validateTaskId(this.#taskIdFactory()),principal=input.principal.trim(),ttlMs=input.ttlMs===void 0?DEFAULT_TASK_TTL_MS:input.ttlMs,pollIntervalMs=input.pollIntervalMs??DEFAULT_TASK_POLL_INTERVAL_MS;if(principal.length===0||ttlMs!==null&&(!Number.isSafeInteger(ttlMs)||ttlMs<0)||!Number.isSafeInteger(pollIntervalMs)||pollIntervalMs<0)throw new PmMcpProtocolError("Invalid MCP task creation options",PM_MCP_ERROR_CODES.invalidParams);const timestamp=this.#now().toISOString(),record={version:1,taskId,status:"working",createdAt:timestamp,lastUpdatedAt:timestamp,ttlMs,pollIntervalMs,principal,workerPid:this.#workerPid,consumedInputKeys:[],...input.statusMessage?.trim()?{statusMessage:input.statusMessage.trim().slice(0,MAX_STATUS_MESSAGE_LENGTH)}:{}};return await this.#write(record),{...publicTask(record),resultType:"task"}}async get(taskId,principal){return publicTask(await this.#mutate(taskId,principal,record=>{if(isTerminalTask(record.status))return record;const nowMs=this.#now().getTime(),expired=record.ttlMs!==null&&Date.parse(record.createdAt)+record.ttlMs<=nowMs,unavailableWorker=record.workerPid!==this.#workerPid&&!isProcessAlive(record.workerPid);return!expired&&!unavailableWorker?record:{...record,status:"failed",statusMessage:expired?"Task retention expired before completion.":"Task worker ended before recording a terminal result.",lastUpdatedAt:this.#now().toISOString(),error:{code:-32603,message:expired?"MCP task expired":"MCP task worker unavailable after restart",data:{recoverable:!1,createNewTask:!0}},inputRequests:void 0}}))}async requireInput(input){const requests=parseMcpInputRequests(input.inputRequests,input.requestContext);return publicTask(await this.#mutate(input.taskId,input.principal,record=>{if(isTerminalTask(record.status))return record;const reused=Object.keys(requests).filter(key=>record.consumedInputKeys.includes(key));if(reused.length>0)throw new PmMcpProtocolError("MCP task input request keys must be unique for the task lifetime",PM_MCP_ERROR_CODES.invalidParams,{reused});return{...record,status:"input_required",statusMessage:input.statusMessage?.trim().slice(0,MAX_STATUS_MESSAGE_LENGTH),lastUpdatedAt:this.#now().toISOString(),inputRequests:requests}}))}async update(taskId,principal,inputResponses){const responses=parseMcpInputResponses(inputResponses),acceptedKeys=[];let remainingKeys=[];return await this.#mutate(taskId,principal,record=>{if(record.status!=="input_required"||!record.inputRequests)return record;const outstanding={...record.inputRequests},accepted=record.inputResponses?{...record.inputResponses}:{};for(const[key,response]of Object.entries(responses))Object.prototype.hasOwnProperty.call(outstanding,key)&&(accepted[key]=response,delete outstanding[key],acceptedKeys.push(key));return remainingKeys=Object.keys(outstanding).sort(),acceptedKeys.length===0?record:{...record,status:remainingKeys.length===0?"working":"input_required",lastUpdatedAt:this.#now().toISOString(),inputRequests:remainingKeys.length===0?void 0:outstanding,inputResponses:accepted,consumedInputKeys:[...new Set([...record.consumedInputKeys,...acceptedKeys])].sort()}}),{acceptedKeys:acceptedKeys.sort(),remainingKeys}}async takeInputResponses(taskId,principal){let responses={};return await this.#mutate(taskId,principal,record=>(responses=structuredClone(record.inputResponses??{}),Object.keys(responses).length===0?record:{...record,inputResponses:void 0})),responses}async complete(taskId,principal,result){return publicTask(await this.#mutate(taskId,principal,record=>isTerminalTask(record.status)?record:{...record,status:"completed",statusMessage:"Task completed.",lastUpdatedAt:this.#now().toISOString(),result:structuredClone(result),inputRequests:void 0,error:void 0}))}async fail(taskId,principal,error){const boundedError=parseTaskError(error);return publicTask(await this.#mutate(taskId,principal,record=>isTerminalTask(record.status)?record:{...record,status:"failed",statusMessage:boundedError.message,lastUpdatedAt:this.#now().toISOString(),error:boundedError,inputRequests:void 0,result:void 0}))}async cancel(taskId,principal){return publicTask(await this.#mutate(taskId,principal,record=>isTerminalTask(record.status)?record:{...record,status:"cancelled",statusMessage:"Task cancelled by the client.",lastUpdatedAt:this.#now().toISOString(),inputRequests:void 0,result:void 0,error:void 0}))}}function createMcpTaskStore(options){return new PmMcpTaskStore(options)}export{PM_MCP_TASKS_EXTENSION,PM_MCP_TASK_STATUSES,PmMcpTaskStore,createMcpTaskStore};
3
3
  //# sourceMappingURL=tasks.js.map
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7d591d0b-f009-519c-8024-c6fa18effb8e")}catch(e2){}})();import{PM_MCP_ERROR_CODES,PM_MCP_PROTOCOL_VERSION,PmMcpProtocolError,isMcpRecord,resolveMcpRequestContext}from"./protocol.js";const BASE64_SENTINEL_PATTERN=/^=\?base64\?([A-Za-z0-9+/]*={0,2})\?=$/u;const HEADER_NAME_TOKEN_PATTERN=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u;const PLAIN_HEADER_VALUE_PATTERN=/^[\t\x20-\x7E]*$/u;const REQUIRED_NAME_METHODS=new Set(["prompts/get","resources/read","tools/call"]);function normalizedHeaders(headers){const normalized=new Map;for(const[name,value]of Object.entries(headers)){if(value===void 0)continue;const entry=typeof value==="string"?value:value.join(", ");normalized.set(name.toLowerCase(),entry)}return normalized}function failHeader(message,header){throw new PmMcpProtocolError(message,PM_MCP_ERROR_CODES.headerMismatch,{header})}function encodeMcpHttpHeaderValue(value){const serialized=typeof value==="boolean"?String(value).toLowerCase():String(value);if(serialized.length>0&&serialized.trim()===serialized&&PLAIN_HEADER_VALUE_PATTERN.test(serialized)&&!BASE64_SENTINEL_PATTERN.test(serialized)){return serialized}return`=?base64?${Buffer.from(serialized,"utf8").toString("base64")}?=`}function decodeMcpHttpHeaderValue(value,header){const sentinel=BASE64_SENTINEL_PATTERN.exec(value);if(sentinel){const encoded=sentinel[1];const decoded=Buffer.from(encoded,"base64");if(decoded.toString("base64")!==encoded||decoded.length===0){return failHeader("Malformed MCP Base64 header value",header)}return decoded.toString("utf8")}if(value.length===0||value.trim()!==value||!PLAIN_HEADER_VALUE_PATTERN.test(value)){return failHeader("Malformed MCP header value",header)}return value}function containsHeaderAnnotation(value){if(Array.isArray(value))return value.some(containsHeaderAnnotation);if(!isMcpRecord(value))return false;return Object.prototype.hasOwnProperty.call(value,"x-mcp-header")||Object.values(value).some(containsHeaderAnnotation)}function parseMcpHeaderAnnotation(propertySchema,propertyPath,names){const annotation=propertySchema["x-mcp-header"];if(annotation===void 0)return void 0;const type=propertySchema.type;if(typeof annotation!=="string"||!HEADER_NAME_TOKEN_PATTERN.test(annotation)||!["boolean","integer","string"].includes(String(type))||names.has(annotation.toLowerCase())){throw new PmMcpProtocolError("Invalid MCP x-mcp-header annotation",PM_MCP_ERROR_CODES.invalidParams,{field:propertyPath.join("."),annotation})}names.add(annotation.toLowerCase());return{name:annotation,path:propertyPath,type}}function collectMcpHeaderAnnotations(schema){if(!isMcpRecord(schema)){throw new PmMcpProtocolError("Invalid MCP tool schema",PM_MCP_ERROR_CODES.invalidParams,{field:"inputSchema",expected:"object"})}const annotations=[];const names=new Set;const visitProperties=(node,path)=>{const properties=node.properties;if(properties===void 0)return;if(!isMcpRecord(properties)){throw new PmMcpProtocolError("Invalid MCP tool schema properties",PM_MCP_ERROR_CODES.invalidParams,{field:"inputSchema.properties"})}for(const[property,propertySchema]of Object.entries(properties)){if(!isMcpRecord(propertySchema))continue;const propertyPath=[...path,property];const annotation=parseMcpHeaderAnnotation(propertySchema,propertyPath,names);if(annotation)annotations.push(annotation);for(const[keyword,nested]of Object.entries(propertySchema)){if(keyword!=="properties"&&keyword!=="x-mcp-header"&&containsHeaderAnnotation(nested)){throw new PmMcpProtocolError("MCP x-mcp-header is not statically reachable",PM_MCP_ERROR_CODES.invalidParams,{field:propertyPath.join("."),keyword})}}visitProperties(propertySchema,propertyPath)}};for(const[keyword,nested]of Object.entries(schema)){if(keyword!=="properties"&&containsHeaderAnnotation(nested)){throw new PmMcpProtocolError("MCP x-mcp-header is not statically reachable",PM_MCP_ERROR_CODES.invalidParams,{field:"inputSchema",keyword})}}visitProperties(schema,[]);return annotations}function valueAtPath(value,path){let current=value;for(const part of path){if(!isMcpRecord(current))return void 0;current=current[part]}return current}function mirroredName(method,params){const value=method==="resources/read"?params.uri:params.name;return typeof value==="string"?value:void 0}function buildMcpCustomRequestHeaders(params,toolSchema){const argumentsValue=isMcpRecord(params.arguments)?params.arguments:{};const headers={};for(const annotation of collectMcpHeaderAnnotations(toolSchema)){const value=valueAtPath(argumentsValue,annotation.path);if(value===void 0||value===null)continue;const valid=annotation.type==="integer"&&typeof value==="number"&&Number.isSafeInteger(value)||annotation.type==="boolean"&&typeof value==="boolean"||annotation.type==="string"&&typeof value==="string";if(!valid){throw new PmMcpProtocolError("Invalid MCP custom header argument",PM_MCP_ERROR_CODES.invalidParams,{field:annotation.path.join("."),expected:annotation.type})}headers[`Mcp-Param-${annotation.name}`]=encodeMcpHttpHeaderValue(value)}return headers}function buildMcpHttpRequestHeaders(input){const params=isMcpRecord(input.request.params)?input.request.params:void 0;const context=resolveMcpRequestContext(params);const method=input.request.method;if(typeof method!=="string"||method.length===0){return failHeader("Missing MCP request method","Mcp-Method")}const headers={Accept:"application/json, text/event-stream","Content-Type":"application/json","MCP-Protocol-Version":context.protocolVersion,"Mcp-Method":method};const name=mirroredName(method,params);if(REQUIRED_NAME_METHODS.has(method)){if(name===void 0)return failHeader("Missing MCP request name","Mcp-Name");headers["Mcp-Name"]=encodeMcpHttpHeaderValue(name)}if(method==="tools/call"&&input.toolSchema!==void 0){Object.assign(headers,buildMcpCustomRequestHeaders(params,input.toolSchema))}return headers}function validateMcpRequiredRequestHeaders(headers,request){const method=request.method;if(typeof method!=="string"||method.length===0){failHeader("Missing MCP request method","Mcp-Method")}const params=isMcpRecord(request.params)?request.params:void 0;const expectedProtocol=resolveMcpRequestContext(params).protocolVersion;if(headers.get("mcp-protocol-version")!==expectedProtocol){failHeader("MCP protocol header does not match request metadata","MCP-Protocol-Version")}if(headers.get("mcp-method")!==method){failHeader("MCP method header does not match request body","Mcp-Method")}if(REQUIRED_NAME_METHODS.has(method)){const headerName=headers.get("mcp-name");const name=mirroredName(method,params);if(headerName===void 0||name===void 0||decodeMcpHttpHeaderValue(headerName,"Mcp-Name")!==name){failHeader("MCP name header does not match request body","Mcp-Name")}}if(headers.has("last-event-id")){failHeader("MCP SSE resumability is not supported","Last-Event-ID")}}function customHeaderMatches(annotation,value,decoded){if(annotation.type==="integer"){return typeof value==="number"&&Number.isSafeInteger(value)&&Number(decoded)===value}if(annotation.type==="boolean"){return typeof value==="boolean"&&decoded===String(value)}return typeof value==="string"&&decoded===value}function validateMcpCustomRequestHeaders(input){const argumentsValue=isMcpRecord(input.params.arguments)?input.params.arguments:{};for(const annotation of collectMcpHeaderAnnotations(input.toolSchema)){const value=valueAtPath(argumentsValue,annotation.path);const header=`Mcp-Param-${annotation.name}`;const mirrored=input.headers.get(header.toLowerCase());if(value===void 0||value===null){if(mirrored!==void 0)failHeader("Unexpected MCP parameter header",header);continue}if(mirrored===void 0)failHeader("Missing MCP parameter header",header);if(!customHeaderMatches(annotation,value,decodeMcpHttpHeaderValue(mirrored,header))){failHeader("MCP parameter header does not match request body",header)}}}function validateMcpHttpRequestHeaders(input){const headers=normalizedHeaders(input.headers);const method=typeof input.request.method==="string"?input.request.method:"";validateMcpRequiredRequestHeaders(headers,input.request);if(method!=="tools/call"||input.toolSchema===void 0)return;validateMcpCustomRequestHeaders({headers,params:input.request.params,toolSchema:input.toolSchema})}const PM_MCP_HTTP_PROTOCOL_VERSION=PM_MCP_PROTOCOL_VERSION;export{PM_MCP_HTTP_PROTOCOL_VERSION,buildMcpHttpRequestHeaders,collectMcpHeaderAnnotations,decodeMcpHttpHeaderValue,encodeMcpHttpHeaderValue,validateMcpHttpRequestHeaders};
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]="3681273a-e101-57a0-9446-982c450e7183")}catch{}})();import{PM_MCP_ERROR_CODES,PM_MCP_PROTOCOL_VERSION,PmMcpProtocolError,isMcpRecord,resolveMcpRequestContext}from"./protocol.js";const BASE64_SENTINEL_PATTERN=/^=\?base64\?([A-Za-z0-9+/]*={0,2})\?=$/u,HEADER_NAME_TOKEN_PATTERN=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u,PLAIN_HEADER_VALUE_PATTERN=/^[\t\x20-\x7E]*$/u,REQUIRED_NAME_METHODS=new Set(["prompts/get","resources/read","tools/call"]);function normalizedHeaders(headers){const normalized=new Map;for(const[name,value]of Object.entries(headers)){if(value===void 0)continue;const entry=typeof value=="string"?value:value.join(", ");normalized.set(name.toLowerCase(),entry)}return normalized}function failHeader(message,header){throw new PmMcpProtocolError(message,PM_MCP_ERROR_CODES.headerMismatch,{header})}function encodeMcpHttpHeaderValue(value){const serialized=typeof value=="boolean"?String(value).toLowerCase():String(value);return serialized.length>0&&serialized.trim()===serialized&&PLAIN_HEADER_VALUE_PATTERN.test(serialized)&&!BASE64_SENTINEL_PATTERN.test(serialized)?serialized:`=?base64?${Buffer.from(serialized,"utf8").toString("base64")}?=`}function decodeMcpHttpHeaderValue(value,header){const sentinel=BASE64_SENTINEL_PATTERN.exec(value);if(sentinel){const encoded=sentinel[1],decoded=Buffer.from(encoded,"base64");return decoded.toString("base64")!==encoded||decoded.length===0?failHeader("Malformed MCP Base64 header value",header):decoded.toString("utf8")}return value.length===0||value.trim()!==value||!PLAIN_HEADER_VALUE_PATTERN.test(value)?failHeader("Malformed MCP header value",header):value}function containsHeaderAnnotation(value){return Array.isArray(value)?value.some(containsHeaderAnnotation):isMcpRecord(value)?Object.prototype.hasOwnProperty.call(value,"x-mcp-header")||Object.values(value).some(containsHeaderAnnotation):!1}function parseMcpHeaderAnnotation(propertySchema,propertyPath,names){const annotation=propertySchema["x-mcp-header"];if(annotation===void 0)return;const type=propertySchema.type;if(typeof annotation!="string"||!HEADER_NAME_TOKEN_PATTERN.test(annotation)||!["boolean","integer","string"].includes(String(type))||names.has(annotation.toLowerCase()))throw new PmMcpProtocolError("Invalid MCP x-mcp-header annotation",PM_MCP_ERROR_CODES.invalidParams,{field:propertyPath.join("."),annotation});return names.add(annotation.toLowerCase()),{name:annotation,path:propertyPath,type}}function collectMcpHeaderAnnotations(schema){if(!isMcpRecord(schema))throw new PmMcpProtocolError("Invalid MCP tool schema",PM_MCP_ERROR_CODES.invalidParams,{field:"inputSchema",expected:"object"});const annotations=[],names=new Set,visitProperties=(node,path)=>{const properties=node.properties;if(properties!==void 0){if(!isMcpRecord(properties))throw new PmMcpProtocolError("Invalid MCP tool schema properties",PM_MCP_ERROR_CODES.invalidParams,{field:"inputSchema.properties"});for(const[property,propertySchema]of Object.entries(properties)){if(!isMcpRecord(propertySchema))continue;const propertyPath=[...path,property],annotation=parseMcpHeaderAnnotation(propertySchema,propertyPath,names);annotation&&annotations.push(annotation);for(const[keyword,nested]of Object.entries(propertySchema))if(keyword!=="properties"&&keyword!=="x-mcp-header"&&containsHeaderAnnotation(nested))throw new PmMcpProtocolError("MCP x-mcp-header is not statically reachable",PM_MCP_ERROR_CODES.invalidParams,{field:propertyPath.join("."),keyword});visitProperties(propertySchema,propertyPath)}}};for(const[keyword,nested]of Object.entries(schema))if(keyword!=="properties"&&containsHeaderAnnotation(nested))throw new PmMcpProtocolError("MCP x-mcp-header is not statically reachable",PM_MCP_ERROR_CODES.invalidParams,{field:"inputSchema",keyword});return visitProperties(schema,[]),annotations}function valueAtPath(value,path){let current=value;for(const part of path){if(!isMcpRecord(current))return;current=current[part]}return current}function mirroredName(method,params){const value=method==="resources/read"?params.uri:params.name;return typeof value=="string"?value:void 0}function buildMcpCustomRequestHeaders(params,toolSchema){const argumentsValue=isMcpRecord(params.arguments)?params.arguments:{},headers={};for(const annotation of collectMcpHeaderAnnotations(toolSchema)){const value=valueAtPath(argumentsValue,annotation.path);if(value!=null){if(!(annotation.type==="integer"&&typeof value=="number"&&Number.isSafeInteger(value)||annotation.type==="boolean"&&typeof value=="boolean"||annotation.type==="string"&&typeof value=="string"))throw new PmMcpProtocolError("Invalid MCP custom header argument",PM_MCP_ERROR_CODES.invalidParams,{field:annotation.path.join("."),expected:annotation.type});headers[`Mcp-Param-${annotation.name}`]=encodeMcpHttpHeaderValue(value)}}return headers}function buildMcpHttpRequestHeaders(input){const params=isMcpRecord(input.request.params)?input.request.params:void 0,context=resolveMcpRequestContext(params),method=input.request.method;if(typeof method!="string"||method.length===0)return failHeader("Missing MCP request method","Mcp-Method");const headers={Accept:"application/json, text/event-stream","Content-Type":"application/json","MCP-Protocol-Version":context.protocolVersion,"Mcp-Method":method},name=mirroredName(method,params);if(REQUIRED_NAME_METHODS.has(method)){if(name===void 0)return failHeader("Missing MCP request name","Mcp-Name");headers["Mcp-Name"]=encodeMcpHttpHeaderValue(name)}return method==="tools/call"&&input.toolSchema!==void 0&&Object.assign(headers,buildMcpCustomRequestHeaders(params,input.toolSchema)),headers}function validateMcpRequiredRequestHeaders(headers,request){const method=request.method;(typeof method!="string"||method.length===0)&&failHeader("Missing MCP request method","Mcp-Method");const params=isMcpRecord(request.params)?request.params:void 0,expectedProtocol=resolveMcpRequestContext(params).protocolVersion;if(headers.get("mcp-protocol-version")!==expectedProtocol&&failHeader("MCP protocol header does not match request metadata","MCP-Protocol-Version"),headers.get("mcp-method")!==method&&failHeader("MCP method header does not match request body","Mcp-Method"),REQUIRED_NAME_METHODS.has(method)){const headerName=headers.get("mcp-name"),name=mirroredName(method,params);(headerName===void 0||name===void 0||decodeMcpHttpHeaderValue(headerName,"Mcp-Name")!==name)&&failHeader("MCP name header does not match request body","Mcp-Name")}headers.has("last-event-id")&&failHeader("MCP SSE resumability is not supported","Last-Event-ID")}function customHeaderMatches(annotation,value,decoded){return annotation.type==="integer"?typeof value=="number"&&Number.isSafeInteger(value)&&Number(decoded)===value:annotation.type==="boolean"?typeof value=="boolean"&&decoded===String(value):typeof value=="string"&&decoded===value}function validateMcpCustomRequestHeaders(input){const argumentsValue=isMcpRecord(input.params.arguments)?input.params.arguments:{};for(const annotation of collectMcpHeaderAnnotations(input.toolSchema)){const value=valueAtPath(argumentsValue,annotation.path),header=`Mcp-Param-${annotation.name}`,mirrored=input.headers.get(header.toLowerCase());if(value==null){mirrored!==void 0&&failHeader("Unexpected MCP parameter header",header);continue}mirrored===void 0&&failHeader("Missing MCP parameter header",header),customHeaderMatches(annotation,value,decodeMcpHttpHeaderValue(mirrored,header))||failHeader("MCP parameter header does not match request body",header)}}function validateMcpHttpRequestHeaders(input){const headers=normalizedHeaders(input.headers),method=typeof input.request.method=="string"?input.request.method:"";validateMcpRequiredRequestHeaders(headers,input.request),!(method!=="tools/call"||input.toolSchema===void 0)&&validateMcpCustomRequestHeaders({headers,params:input.request.params,toolSchema:input.toolSchema})}const PM_MCP_HTTP_PROTOCOL_VERSION=PM_MCP_PROTOCOL_VERSION;export{PM_MCP_HTTP_PROTOCOL_VERSION,buildMcpHttpRequestHeaders,collectMcpHeaderAnnotations,decodeMcpHttpHeaderValue,encodeMcpHttpHeaderValue,validateMcpHttpRequestHeaders};
2
2
  //# sourceMappingURL=transport.js.map
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5fd3624a-d36b-58e6-8053-f2c0626e0c10")}catch(e2){}})();import{runHistoryRepair}from"../history-repair.js";import{isOriginalGitStateRestored}from"./receipt-operation.js";import{markMergeReceiptReconciled,summarizeMergeReceipt}from"./receipts.js";async function settleAbandonedMergeReceipts(params){if(params.cwd===null)return[];const settled=[];for(const receipt of params.receipts){if(receipt.operation===void 0||!await isOriginalGitStateRestored(params.cwd,receipt.item_path,receipt.operation))continue;const mergeAbandonmentProof={gitWorkspaceRoot:params.cwd,receipt};await runHistoryRepair(receipt.item_id,{dryRun:true,mergeAbandonmentProof},params.global);if(!params.dryRun){await runHistoryRepair(receipt.item_id,{author:params.author??params.global.author,mergeAbandonmentProof,message:params.message??"Settle rebase receipt after exact original Git state restoration",auditOperation:"merge_reconcile",forceAuditEntry:true,auditContext:{merge:{abandoned_receipts:[{...summarizeMergeReceipt(receipt),reason:"original_git_state_restored",operation:receipt.operation}]}}},params.global);await markMergeReceiptReconciled(params.cwd,receipt,{requireExisting:true,settlement:"original_git_state_restored"})}settled.push(receipt.id)}return settled}export{settleAbandonedMergeReceipts};
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]="450eabe6-334a-587c-b838-5ca42519296f")}catch{}})();import{runHistoryRepair}from"../history-repair.js";import{isOriginalGitStateRestored}from"./receipt-operation.js";import{markMergeReceiptReconciled,summarizeMergeReceipt}from"./receipts.js";async function settleAbandonedMergeReceipts(params){if(params.cwd===null)return[];const settled=[];for(const receipt of params.receipts){if(receipt.operation===void 0||!await isOriginalGitStateRestored(params.cwd,receipt.item_path,receipt.operation))continue;const mergeAbandonmentProof={gitWorkspaceRoot:params.cwd,receipt};await runHistoryRepair(receipt.item_id,{dryRun:!0,mergeAbandonmentProof},params.global),params.dryRun||(await runHistoryRepair(receipt.item_id,{author:params.author??params.global.author,mergeAbandonmentProof,message:params.message??"Settle rebase receipt after exact original Git state restoration",auditOperation:"merge_reconcile",forceAuditEntry:!0,auditContext:{merge:{abandoned_receipts:[{...summarizeMergeReceipt(receipt),reason:"original_git_state_restored",operation:receipt.operation}]}}},params.global),await markMergeReceiptReconciled(params.cwd,receipt,{requireExisting:!0,settlement:"original_git_state_restored"})),settled.push(receipt.id)}return settled}export{settleAbandonedMergeReceipts};
2
2
  //# sourceMappingURL=abandoned-receipts.js.map
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="47487ad3-22a0-52ac-8a42-ebaca439cb6e")}catch(e2){}})();import{readFile,writeFile}from"node:fs/promises";import path from"node:path";import{getActiveExtensionRegistrations}from"../../core/extensions/index.js";import{collectRegisteredItemFieldNames}from"../../core/extensions/item-fields.js";import{pathExists}from"../../core/fs/fs-utils.js";import{parseItemDocument}from"../../core/item/item-format.js";import{EXIT_CODE}from"../../core/shared/constants.js";import{PmCliError}from"../../core/shared/errors.js";import{nowIso}from"../../core/shared/time.js";import{getSettingsPath,resolvePmRoot}from"../../core/store/paths.js";import{readSettings}from"../../core/store/settings.js";import{hashItemScalarDecisionValue,mergeHistoryStreams,mergeItemDocuments,mergeJsonDocuments,mergeRelationshipEventStreams}from"./three-way.js";import{captureMergeReceiptOperation}from"./receipt-operation.js";import{summarizeMergeReceipt,writeMergeReceipt}from"./receipts.js";const MERGE_DRIVER_ARTIFACT_VALUES=["item","history","relationship","json"];function resolveArtifact(value){const normalized=value.trim().toLowerCase();if(MERGE_DRIVER_ARTIFACT_VALUES.includes(normalized)){return normalized}throw new PmCliError(`Unknown merge artifact "${value}". Supported values: ${MERGE_DRIVER_ARTIFACT_VALUES.join(", ")}.`,EXIT_CODE.USAGE)}function resolvePreferredSide(value){if(value===void 0){return"ours"}const normalized=value.trim().toLowerCase();if(normalized==="ours"||normalized==="theirs"){return normalized}throw new PmCliError(`Unknown --prefer value "${value}". Supported values: ours, theirs.`,EXIT_CODE.USAGE)}async function readSideFile(filePath,label){try{return await readFile(filePath,"utf8")}catch{throw new PmCliError(`Cannot read merge ${label} file at ${filePath}.`,EXIT_CODE.NOT_FOUND)}}async function loadOptionalSettings(global2){const pmRoot=resolvePmRoot(process.cwd(),global2.path);if(!await pathExists(getSettingsPath(pmRoot))){return null}return readSettings(pmRoot)}function itemFormatForPath(filePath,settings){if(filePath.endsWith(".md")){return"json_markdown"}if(filePath.endsWith(".toon")){return"toon"}return settings?.item_format??"toon"}async function runMergeDriver(options,global2){const artifact=resolveArtifact(options.artifact);const preferred=resolvePreferredSide(options.prefer);const outputPath=path.resolve(options.outputPath??options.oursPath);const[baseRaw,oursRaw,theirsRaw]=await Promise.all([readSideFile(options.basePath,"base"),readSideFile(options.oursPath,"ours"),readSideFile(options.theirsPath,"theirs")]);let merged;let receiptInput;const conflicts=[];const result={};if(artifact==="history"){const historyMerge=mergeHistoryStreams(baseRaw,oursRaw,theirsRaw);merged=historyMerge.merged;result.history={strategy:historyMerge.strategy,common_entries:historyMerge.common_entries,entries_from_ours:historyMerge.entries_from_ours,entries_from_theirs:historyMerge.entries_from_theirs,entries_total:historyMerge.entries_total,reanchored:historyMerge.reanchored}}else if(artifact==="relationship"){const relationshipMerge=mergeRelationshipEventStreams(baseRaw,oursRaw,theirsRaw);merged=relationshipMerge.merged;result.relationship={strategy:relationshipMerge.strategy,common_entries:relationshipMerge.common_entries,entries_from_ours:relationshipMerge.entries_from_ours,entries_from_theirs:relationshipMerge.entries_from_theirs,entries_total:relationshipMerge.entries_total,reanchored:relationshipMerge.reanchored}}else if(artifact==="item"){const settings=await loadOptionalSettings(global2);const itemFormat=itemFormatForPath(options.itemPath??outputPath,settings);const extensionFieldNames=collectRegisteredItemFieldNames(getActiveExtensionRegistrations());const itemMerge=mergeItemDocuments(baseRaw,oursRaw,theirsRaw,{format:itemFormat,schema:settings?.schema,extensionFieldNames,preferred,conflictResolution:"latest_document_update"});merged=itemMerge.merged;conflicts.push(...itemMerge.conflict_fields);result.item={fields_from_theirs:itemMerge.fields_from_theirs,union_fields:itemMerge.union_fields,conflict_resolution:"latest_document_update",requested_preference_applied:false};if(options.itemPath!==void 0){const mergedDocument=parseItemDocument(merged,{format:itemFormat,schema:settings?.schema,extensionFieldNames});const mergedMetadata=mergedDocument.metadata;const receiptFields=[...new Set([...itemMerge.fields_from_theirs,...itemMerge.union_fields,...itemMerge.conflict_decisions.map(decision=>decision.field)])];receiptInput={cwd:process.cwd(),itemPath:options.itemPath,preferred,conflictResolution:"latest_document_update",fieldsFromTheirs:itemMerge.fields_from_theirs,unionFields:itemMerge.union_fields,mergedFieldHashes:Object.fromEntries(receiptFields.map(field=>[field,hashItemScalarDecisionValue(field==="body"?mergedDocument.body:mergedMetadata[field])])),decisions:itemMerge.conflict_decisions,operation:await captureMergeReceiptOperation(process.cwd(),options.itemPath)}}}else{const jsonMerge=mergeJsonDocuments(baseRaw,oursRaw,theirsRaw,{preferred});merged=jsonMerge.merged;conflicts.push(...jsonMerge.conflict_paths);result.json={paths_from_theirs:jsonMerge.paths_from_theirs}}await writeFile(outputPath,merged,"utf8");if(receiptInput!==void 0){const receipt=await writeMergeReceipt(receiptInput);if(receipt!==null){result.receipt=summarizeMergeReceipt(receipt)}}const guidance=[];if(conflicts.length>0){const receiptGuidance=result.receipt===void 0?'Run "pm merge report" to inspect clone-local merge evidence.':`Run "pm merge report" and correlate receipt ${result.receipt.receipt_id} with item ${result.receipt.item_id}; clone-local discarded values are never copied into this result.`;guidance.push(`Both branches changed ${conflicts.join(", ")}; the item driver kept the value from the later document update, with stable value order only as an equal-timestamp tie-break. --prefer does not apply to convergent item scalar conflicts. ${receiptGuidance} Review the merged file, re-apply the discarded change if needed, then "git add" it.`)}if(artifact==="history"&&result.history?.reanchored){guidance.push('The merged history chain was re-anchored. Run "pm merge reconcile --dry-run" to inspect the complete post-merge repair, then "pm merge reconcile" to apply it; use --force only after explicitly accepting reported discards.')}return{ok:conflicts.length===0,artifact,output_path:outputPath,requested_preference:preferred,conflicts,...result,guidance,generated_at:nowIso()}}export{MERGE_DRIVER_ARTIFACT_VALUES,runMergeDriver};
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]="abbd522e-582e-584b-bf25-e065173918f4")}catch{}})();import{readFile,writeFile}from"node:fs/promises";import path from"node:path";import{getActiveExtensionRegistrations}from"../../core/extensions/index.js";import{collectRegisteredItemFieldNames}from"../../core/extensions/item-fields.js";import{pathExists}from"../../core/fs/fs-utils.js";import{parseItemDocument}from"../../core/item/item-format.js";import{EXIT_CODE}from"../../core/shared/constants.js";import{PmCliError}from"../../core/shared/errors.js";import{nowIso}from"../../core/shared/time.js";import{getSettingsPath,resolvePmRoot}from"../../core/store/paths.js";import{readSettings}from"../../core/store/settings.js";import{hashItemScalarDecisionValue,mergeHistoryStreams,mergeItemDocuments,mergeJsonDocuments,mergeRelationshipEventStreams}from"./three-way.js";import{captureMergeReceiptOperation}from"./receipt-operation.js";import{summarizeMergeReceipt,writeMergeReceipt}from"./receipts.js";const MERGE_DRIVER_ARTIFACT_VALUES=["item","history","relationship","json"];function resolveArtifact(value){const normalized=value.trim().toLowerCase();if(MERGE_DRIVER_ARTIFACT_VALUES.includes(normalized))return normalized;throw new PmCliError(`Unknown merge artifact "${value}". Supported values: ${MERGE_DRIVER_ARTIFACT_VALUES.join(", ")}.`,EXIT_CODE.USAGE)}function resolvePreferredSide(value){if(value===void 0)return"ours";const normalized=value.trim().toLowerCase();if(normalized==="ours"||normalized==="theirs")return normalized;throw new PmCliError(`Unknown --prefer value "${value}". Supported values: ours, theirs.`,EXIT_CODE.USAGE)}async function readSideFile(filePath,label){try{return await readFile(filePath,"utf8")}catch{throw new PmCliError(`Cannot read merge ${label} file at ${filePath}.`,EXIT_CODE.NOT_FOUND)}}async function loadOptionalSettings(global2){const pmRoot=resolvePmRoot(process.cwd(),global2.path);return await pathExists(getSettingsPath(pmRoot))?readSettings(pmRoot):null}function itemFormatForPath(filePath,settings){return filePath.endsWith(".md")?"json_markdown":filePath.endsWith(".toon")?"toon":settings?.item_format??"toon"}async function runMergeDriver(options,global2){const artifact=resolveArtifact(options.artifact),preferred=resolvePreferredSide(options.prefer),outputPath=path.resolve(options.outputPath??options.oursPath),[baseRaw,oursRaw,theirsRaw]=await Promise.all([readSideFile(options.basePath,"base"),readSideFile(options.oursPath,"ours"),readSideFile(options.theirsPath,"theirs")]);let merged,receiptInput;const conflicts=[],result={};if(artifact==="history"){const historyMerge=mergeHistoryStreams(baseRaw,oursRaw,theirsRaw);merged=historyMerge.merged,result.history={strategy:historyMerge.strategy,common_entries:historyMerge.common_entries,entries_from_ours:historyMerge.entries_from_ours,entries_from_theirs:historyMerge.entries_from_theirs,entries_total:historyMerge.entries_total,reanchored:historyMerge.reanchored}}else if(artifact==="relationship"){const relationshipMerge=mergeRelationshipEventStreams(baseRaw,oursRaw,theirsRaw);merged=relationshipMerge.merged,result.relationship={strategy:relationshipMerge.strategy,common_entries:relationshipMerge.common_entries,entries_from_ours:relationshipMerge.entries_from_ours,entries_from_theirs:relationshipMerge.entries_from_theirs,entries_total:relationshipMerge.entries_total,reanchored:relationshipMerge.reanchored}}else if(artifact==="item"){const settings=await loadOptionalSettings(global2),itemFormat=itemFormatForPath(options.itemPath??outputPath,settings),extensionFieldNames=collectRegisteredItemFieldNames(getActiveExtensionRegistrations()),itemMerge=mergeItemDocuments(baseRaw,oursRaw,theirsRaw,{format:itemFormat,schema:settings?.schema,extensionFieldNames,preferred,conflictResolution:"latest_document_update"});if(merged=itemMerge.merged,conflicts.push(...itemMerge.conflict_fields),result.item={fields_from_theirs:itemMerge.fields_from_theirs,union_fields:itemMerge.union_fields,conflict_resolution:"latest_document_update",requested_preference_applied:!1},options.itemPath!==void 0){const mergedDocument=parseItemDocument(merged,{format:itemFormat,schema:settings?.schema,extensionFieldNames}),mergedMetadata=mergedDocument.metadata,receiptFields=[...new Set([...itemMerge.fields_from_theirs,...itemMerge.union_fields,...itemMerge.conflict_decisions.map(decision=>decision.field)])];receiptInput={cwd:process.cwd(),itemPath:options.itemPath,preferred,conflictResolution:"latest_document_update",fieldsFromTheirs:itemMerge.fields_from_theirs,unionFields:itemMerge.union_fields,mergedFieldHashes:Object.fromEntries(receiptFields.map(field=>[field,hashItemScalarDecisionValue(field==="body"?mergedDocument.body:mergedMetadata[field])])),decisions:itemMerge.conflict_decisions,operation:await captureMergeReceiptOperation(process.cwd(),options.itemPath)}}}else{const jsonMerge=mergeJsonDocuments(baseRaw,oursRaw,theirsRaw,{preferred});merged=jsonMerge.merged,conflicts.push(...jsonMerge.conflict_paths),result.json={paths_from_theirs:jsonMerge.paths_from_theirs}}if(await writeFile(outputPath,merged,"utf8"),receiptInput!==void 0){const receipt=await writeMergeReceipt(receiptInput);receipt!==null&&(result.receipt=summarizeMergeReceipt(receipt))}const guidance=[];if(conflicts.length>0){const receiptGuidance=result.receipt===void 0?'Run "pm merge report" to inspect clone-local merge evidence.':`Run "pm merge report" and correlate receipt ${result.receipt.receipt_id} with item ${result.receipt.item_id}; clone-local discarded values are never copied into this result.`;guidance.push(`Both branches changed ${conflicts.join(", ")}; the item driver kept the value from the later document update, with stable value order only as an equal-timestamp tie-break. --prefer does not apply to convergent item scalar conflicts. ${receiptGuidance} Review the merged file, re-apply the discarded change if needed, then "git add" it.`)}return artifact==="history"&&result.history?.reanchored&&guidance.push('The merged history chain was re-anchored. Run "pm merge reconcile --dry-run" to inspect the complete post-merge repair, then "pm merge reconcile" to apply it; use --force only after explicitly accepting reported discards.'),{ok:conflicts.length===0,artifact,output_path:outputPath,requested_preference:preferred,conflicts,...result,guidance,generated_at:nowIso()}}export{MERGE_DRIVER_ARTIFACT_VALUES,runMergeDriver};
2
2
  //# sourceMappingURL=driver.js.map
@@ -1,2 +1,2 @@
1
- !(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4175f7f5-a689-5d05-982a-f92e21bc83e7")}catch(e2){}})();import{ITEM_SCALAR_MISSING_VALUE,ITEM_LATEST_TIMESTAMP_FIELDS,ITEM_UNION_COLLECTION_FIELDS,encodeItemScalarDecisionValue,hashItemScalarDecisionValue,isItemScalarMissingValue,mergeHistoryStreams,mergeItemDocuments,mergeJsonDocuments,mergeRelationshipEventStreams}from"./three-way.js";import{inspectMergeReceiptEvidence,listMergeReceipts,markMergeReceiptReconciled,runMergeReceiptEvidenceReport,runMergeReceiptReport,summarizeMergeReceipt}from"./receipts.js";import{MERGE_DRIVER_ARTIFACT_VALUES,runMergeDriver}from"./driver.js";import{auditMergeAttributeFence,auditMergeDriverConfiguration,buildMergeAttributePatterns,findGitWorkspaceRoot,PM_GITATTRIBUTES_END,PM_GITATTRIBUTES_START,PM_GITATTRIBUTES_V2_END,PM_GITATTRIBUTES_V2_START,refreshMergeAttributeFenceIfInstalled,resolveMergeInstallContext,runMergeInstall}from"./install.js";import{runMergeReconcile}from"./reconcile.js";export{ITEM_LATEST_TIMESTAMP_FIELDS,ITEM_SCALAR_MISSING_VALUE,ITEM_UNION_COLLECTION_FIELDS,MERGE_DRIVER_ARTIFACT_VALUES,PM_GITATTRIBUTES_END,PM_GITATTRIBUTES_START,PM_GITATTRIBUTES_V2_END,PM_GITATTRIBUTES_V2_START,auditMergeAttributeFence,auditMergeDriverConfiguration,buildMergeAttributePatterns,encodeItemScalarDecisionValue,findGitWorkspaceRoot,hashItemScalarDecisionValue,inspectMergeReceiptEvidence,isItemScalarMissingValue,listMergeReceipts,markMergeReceiptReconciled,mergeHistoryStreams,mergeItemDocuments,mergeJsonDocuments,mergeRelationshipEventStreams,refreshMergeAttributeFenceIfInstalled,resolveMergeInstallContext,runMergeDriver,runMergeInstall,runMergeReceiptEvidenceReport,runMergeReceiptReport,runMergeReconcile,summarizeMergeReceipt};
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]="4175f7f5-a689-5d05-982a-f92e21bc83e7")}catch{}})();import{ITEM_SCALAR_MISSING_VALUE,ITEM_LATEST_TIMESTAMP_FIELDS,ITEM_UNION_COLLECTION_FIELDS,encodeItemScalarDecisionValue,hashItemScalarDecisionValue,isItemScalarMissingValue,mergeHistoryStreams,mergeItemDocuments,mergeJsonDocuments,mergeRelationshipEventStreams}from"./three-way.js";import{inspectMergeReceiptEvidence,listMergeReceipts,markMergeReceiptReconciled,runMergeReceiptEvidenceReport,runMergeReceiptReport,summarizeMergeReceipt}from"./receipts.js";import{MERGE_DRIVER_ARTIFACT_VALUES,runMergeDriver}from"./driver.js";import{auditMergeAttributeFence,auditMergeDriverConfiguration,buildMergeAttributePatterns,findGitWorkspaceRoot,PM_GITATTRIBUTES_END,PM_GITATTRIBUTES_START,PM_GITATTRIBUTES_V2_END,PM_GITATTRIBUTES_V2_START,refreshMergeAttributeFenceIfInstalled,resolveMergeInstallContext,runMergeInstall}from"./install.js";import{runMergeReconcile}from"./reconcile.js";export{ITEM_LATEST_TIMESTAMP_FIELDS,ITEM_SCALAR_MISSING_VALUE,ITEM_UNION_COLLECTION_FIELDS,MERGE_DRIVER_ARTIFACT_VALUES,PM_GITATTRIBUTES_END,PM_GITATTRIBUTES_START,PM_GITATTRIBUTES_V2_END,PM_GITATTRIBUTES_V2_START,auditMergeAttributeFence,auditMergeDriverConfiguration,buildMergeAttributePatterns,encodeItemScalarDecisionValue,findGitWorkspaceRoot,hashItemScalarDecisionValue,inspectMergeReceiptEvidence,isItemScalarMissingValue,listMergeReceipts,markMergeReceiptReconciled,mergeHistoryStreams,mergeItemDocuments,mergeJsonDocuments,mergeRelationshipEventStreams,refreshMergeAttributeFenceIfInstalled,resolveMergeInstallContext,runMergeDriver,runMergeInstall,runMergeReceiptEvidenceReport,runMergeReceiptReport,runMergeReconcile,summarizeMergeReceipt};
2
2
  //# sourceMappingURL=index.js.map