@unbrained/pm-cli 2026.10.4 → 2026.10.6

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 (751) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +37 -1
  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.js +4 -4
  93. package/dist/cli/schema/registration.js +2 -2
  94. package/dist/cli/schema-registration-helpers.js +1 -1
  95. package/dist/cli/search-refresh.js +1 -1
  96. package/dist/cli/stats-analytics-json.js +1 -1
  97. package/dist/cli/telemetry-flush.js +1 -1
  98. package/dist/cli-bundle/bundle-manifest.json +163 -163
  99. package/dist/cli-bundle/chunks/{chunk-SMKHR6BM.js → chunk-25EW53VO.js} +89 -88
  100. package/dist/cli-bundle/chunks/chunk-3CCVTV6Q.js +8 -0
  101. package/dist/cli-bundle/chunks/chunk-3REXBTST.js +3 -0
  102. package/dist/cli-bundle/chunks/chunk-4WB55TBC.js +80 -0
  103. package/dist/cli-bundle/chunks/{chunk-7CE2DJMA.js → chunk-6STTPXOC.js} +2 -2
  104. package/dist/cli-bundle/chunks/chunk-ATB4ZZBQ.js +20 -0
  105. package/dist/cli-bundle/chunks/chunk-D4G43LBV.js +238 -0
  106. package/dist/cli-bundle/chunks/chunk-K6D6DMRT.js +31 -0
  107. package/dist/cli-bundle/chunks/chunk-KIRHWPZB.js +2 -0
  108. package/dist/cli-bundle/chunks/chunk-O67BH435.js +6 -0
  109. package/dist/cli-bundle/chunks/chunk-R7CG2DB7.js +2 -0
  110. package/dist/cli-bundle/chunks/chunk-RJHLD64E.js +3 -0
  111. package/dist/cli-bundle/chunks/chunk-TUKO5NF7.js +2 -0
  112. package/dist/cli-bundle/chunks/chunk-UZ7BIUCI.js +2 -0
  113. package/dist/cli-bundle/chunks/{chunk-GZMWISWW.js → chunk-XJD47LUH.js} +3 -3
  114. package/dist/cli-bundle/chunks/{register-list-query-QBGXO5JJ.js → register-list-query-53WYLNZT.js} +11 -11
  115. package/dist/cli-bundle/chunks/register-mutation-34XXUBVI.js +20 -0
  116. package/dist/cli-bundle/chunks/register-operations-WANO6EIM.js +2 -0
  117. package/dist/cli-bundle/chunks/register-setup-WT37UPBQ.js +2 -0
  118. package/dist/cli-bundle/focused-chunks/chunk-6KFKQD2D.js +165 -0
  119. package/dist/cli-bundle/focused-chunks/chunk-FOHRPFIT.js +2 -0
  120. package/dist/cli-bundle/focused-chunks/chunk-GRQXL5G5.js +8 -0
  121. package/dist/cli-bundle/focused-chunks/{chunk-467EW5RL.js → chunk-JZ4WGUVH.js} +3 -3
  122. package/dist/cli-bundle/focused-chunks/chunk-NM3PM6O6.js +3 -0
  123. package/dist/cli-bundle/focused-chunks/chunk-OT7HK7SG.js +2 -0
  124. package/dist/cli-bundle/focused-chunks/{chunk-Q6DJ5DFQ.js → chunk-PCLU34KB.js} +2 -2
  125. package/dist/cli-bundle/focused-chunks/{chunk-HFAW3FJQ.js → chunk-PSXFFQFT.js} +2 -2
  126. package/dist/cli-bundle/focused-chunks/chunk-QQIE4L42.js +2 -0
  127. package/dist/cli-bundle/focused-chunks/chunk-RPUNVKXK.js +2 -0
  128. package/dist/cli-bundle/focused-chunks/chunk-RXSVJPZ7.js +3 -0
  129. package/dist/cli-bundle/focused-chunks/chunk-SPN5QTZ3.js +30 -0
  130. package/dist/cli-bundle/focused-chunks/chunk-SUZJNPGB.js +6 -0
  131. package/dist/cli-bundle/focused-chunks/chunk-W4BG5HHS.js +2 -0
  132. package/dist/cli-bundle/focused-chunks/chunk-Y5HXFDTZ.js +20 -0
  133. package/dist/cli-bundle/focused-chunks/chunk-ZK5SOOPC.js +75 -0
  134. package/dist/cli-bundle/focused-chunks/chunk-ZQK2XUSS.js +12 -0
  135. package/dist/cli-bundle/main.js +25 -25
  136. package/dist/cli-bundle/sdk-authoring.js +1 -1
  137. package/dist/cli-bundle/sdk-contracts.js +2 -2
  138. package/dist/cli-bundle/sdk-core.js +25 -24
  139. package/dist/cli-bundle/sdk-governance.js +1 -1
  140. package/dist/cli-bundle/sdk-graph.js +1 -1
  141. package/dist/cli-bundle/sdk-merge.js +55 -55
  142. package/dist/cli-bundle/sdk-query.js +1 -1
  143. package/dist/cli-bundle/sdk-runtime.js +1 -1
  144. package/dist/cli-bundle/sdk-testing.js +1 -1
  145. package/dist/cli-bundle/sdk.js +10 -10
  146. package/dist/cli.js +1 -1
  147. package/dist/core/checkpoint/checkpoint-gc.js +1 -1
  148. package/dist/core/checkpoint/mutation-checkpoint.js +2 -2
  149. package/dist/core/config/nested-settings.js +1 -1
  150. package/dist/core/config/positional-value.js +1 -1
  151. package/dist/core/diagnostics/remediation.js +1 -1
  152. package/dist/core/extensions/activation-summary-markdown.js +2 -1
  153. package/dist/core/extensions/activation-summary.js +1 -1
  154. package/dist/core/extensions/activation-transaction.js +1 -1
  155. package/dist/core/extensions/capability-usage.js +1 -1
  156. package/dist/core/extensions/command-hook-context.js +1 -1
  157. package/dist/core/extensions/command-metadata-contract.js +1 -1
  158. package/dist/core/extensions/command-visibility-tier.js +1 -1
  159. package/dist/core/extensions/contribution-inventory.js +1 -1
  160. package/dist/core/extensions/exporter-output-contract.js +1 -1
  161. package/dist/core/extensions/extension-candidate.js +1 -1
  162. package/dist/core/extensions/extension-capability-aliases.js +1 -1
  163. package/dist/core/extensions/extension-hook-runtime.js +1 -1
  164. package/dist/core/extensions/extension-policy.js +1 -1
  165. package/dist/core/extensions/extension-registries.js +1 -1
  166. package/dist/core/extensions/extension-runtime-helpers.js +1 -1
  167. package/dist/core/extensions/extension-types.d.ts +2 -0
  168. package/dist/core/extensions/extension-types.js +1 -1
  169. package/dist/core/extensions/flag-definition-validation.js +1 -1
  170. package/dist/core/extensions/flag-value-types.js +1 -1
  171. package/dist/core/extensions/index.js +1 -1
  172. package/dist/core/extensions/item-field-types.js +1 -1
  173. package/dist/core/extensions/item-fields.js +1 -1
  174. package/dist/core/extensions/loader.js +1 -1
  175. package/dist/core/extensions/manifest-parser.js +1 -1
  176. package/dist/core/extensions/manifest-schema.js +1 -1
  177. package/dist/core/extensions/module-graph-snapshot.js +1 -1
  178. package/dist/core/extensions/preflight-ownership.js +1 -1
  179. package/dist/core/extensions/registration-contracts.js +1 -1
  180. package/dist/core/extensions/registration-validation.js +1 -1
  181. package/dist/core/extensions/registration-values.js +1 -1
  182. package/dist/core/extensions/reserved-host-flags.js +1 -1
  183. package/dist/core/extensions/runtime-registrations.js +1 -1
  184. package/dist/core/extensions/service-ownership.js +1 -1
  185. package/dist/core/extensions/version-compat.js +1 -1
  186. package/dist/core/fs/atomic-create.js +1 -1
  187. package/dist/core/fs/fs-utils.js +2 -2
  188. package/dist/core/fs/host-environment-errors.js +1 -1
  189. package/dist/core/fs/index.js +1 -1
  190. package/dist/core/fs/path-utils.js +1 -1
  191. package/dist/core/governance/content-fields.js +1 -1
  192. package/dist/core/governance/issue-codes.js +1 -1
  193. package/dist/core/governance/metadata-coverage.js +1 -1
  194. package/dist/core/history/digest.js +1 -1
  195. package/dist/core/history/drift-cache.js +3 -3
  196. package/dist/core/history/drift-scan.d.ts +4 -0
  197. package/dist/core/history/drift-scan.js +1 -1
  198. package/dist/core/history/event-classification.js +1 -1
  199. package/dist/core/history/event-index.js +8 -7
  200. package/dist/core/history/history-compact-bulk.js +1 -1
  201. package/dist/core/history/history-diff.js +1 -1
  202. package/dist/core/history/history-rewrite.js +1 -1
  203. package/dist/core/history/history-storage-stats.js +1 -1
  204. package/dist/core/history/history-stream-policy.js +1 -1
  205. package/dist/core/history/history.js +2 -2
  206. package/dist/core/history/identity.js +1 -1
  207. package/dist/core/history/index.js +1 -1
  208. package/dist/core/history/operation-contract.js +1 -1
  209. package/dist/core/history/projection.js +1 -1
  210. package/dist/core/history/read.js +1 -1
  211. package/dist/core/history/replay.js +2 -1
  212. package/dist/core/history/tombstone.js +1 -1
  213. package/dist/core/history/version-address.js +1 -1
  214. package/dist/core/history/workspace-history.js +2 -2
  215. package/dist/core/io/body-file.js +1 -1
  216. package/dist/core/io/bulk-ids-input.js +2 -1
  217. package/dist/core/item/actionability.js +1 -1
  218. package/dist/core/item/dependency-reference.js +1 -1
  219. package/dist/core/item/id.js +1 -1
  220. package/dist/core/item/index.js +1 -1
  221. package/dist/core/item/item-format-version.js +1 -1
  222. package/dist/core/item/item-format.js +6 -4
  223. package/dist/core/item/item-record.js +1 -1
  224. package/dist/core/item/item-type-definition.js +1 -1
  225. package/dist/core/item/parent-reference-policy.js +1 -1
  226. package/dist/core/item/parse.js +8 -2
  227. package/dist/core/item/plan-lifecycle.js +1 -1
  228. package/dist/core/item/priority.js +1 -1
  229. package/dist/core/item/sprint-release-format.js +1 -1
  230. package/dist/core/item/status-filter.js +1 -1
  231. package/dist/core/item/status.js +1 -1
  232. package/dist/core/item/toon-decode.js +1 -1
  233. package/dist/core/item/type-registry.js +1 -1
  234. package/dist/core/item/type-synonyms.js +1 -1
  235. package/dist/core/lock/index.js +1 -1
  236. package/dist/core/lock/lock-gc.js +1 -1
  237. package/dist/core/lock/lock.js +3 -3
  238. package/dist/core/output/mutation-projection.js +1 -1
  239. package/dist/core/output/output-control.js +1 -1
  240. package/dist/core/output/output.js +22 -10
  241. package/dist/core/output/query-summary.js +1 -1
  242. package/dist/core/output/tabular.js +3 -1
  243. package/dist/core/packages/manifest.js +1 -1
  244. package/dist/core/packages/root.js +1 -1
  245. package/dist/core/policy/workflow-policy-schema.js +1 -1
  246. package/dist/core/policy/workflow-policy-store.js +1 -1
  247. package/dist/core/policy/workflow-policy.js +1 -1
  248. package/dist/core/profile/profile-describe.js +1 -1
  249. package/dist/core/profile/profile-lint.js +1 -1
  250. package/dist/core/profile/profile-plan.js +1 -1
  251. package/dist/core/profile/profile-presets.js +25 -1
  252. package/dist/core/reproducibility/context.js +1 -1
  253. package/dist/core/schema/fields-file.js +2 -2
  254. package/dist/core/schema/item-types-file.js +2 -2
  255. package/dist/core/schema/runtime-field-filters.js +1 -1
  256. package/dist/core/schema/runtime-field-values.js +1 -1
  257. package/dist/core/schema/runtime-schema.js +2 -2
  258. package/dist/core/schema/status-defs-file.js +2 -2
  259. package/dist/core/schema/status-token.js +1 -1
  260. package/dist/core/schema/type-inference.js +1 -1
  261. package/dist/core/schema/type-presets.js +1 -1
  262. package/dist/core/schema/type-workflows.js +1 -1
  263. package/dist/core/search/background-refresh.js +2 -2
  264. package/dist/core/search/bm25.js +1 -1
  265. package/dist/core/search/cache.js +2 -2
  266. package/dist/core/search/corpus.js +1 -1
  267. package/dist/core/search/embedding-batches.js +1 -1
  268. package/dist/core/search/eval-thresholds.js +1 -1
  269. package/dist/core/search/eval.js +1 -1
  270. package/dist/core/search/http-client.js +1 -1
  271. package/dist/core/search/providers.js +1 -1
  272. package/dist/core/search/relevance.js +1 -1
  273. package/dist/core/search/semantic-defaults.js +1 -1
  274. package/dist/core/search/staleness.js +1 -1
  275. package/dist/core/search/vector-stores.js +2 -2
  276. package/dist/core/search/vectorization-metadata.js +1 -1
  277. package/dist/core/sentry/helpers.js +1 -1
  278. package/dist/core/sentry/instrument.js +1 -1
  279. package/dist/core/session/session-state.js +1 -1
  280. package/dist/core/shared/agent-session-context.js +1 -1
  281. package/dist/core/shared/author.js +5 -1
  282. package/dist/core/shared/command-line.js +1 -1
  283. package/dist/core/shared/command-types.js +1 -1
  284. package/dist/core/shared/conflict-markers.js +1 -1
  285. package/dist/core/shared/constants.js +1 -1
  286. package/dist/core/shared/errors.js +1 -1
  287. package/dist/core/shared/html-entity-decode.js +1 -1
  288. package/dist/core/shared/index.js +1 -1
  289. package/dist/core/shared/item-metadata-contract.js +1 -1
  290. package/dist/core/shared/lazy-module.js +1 -1
  291. package/dist/core/shared/levenshtein.js +1 -1
  292. package/dist/core/shared/memo.js +1 -1
  293. package/dist/core/shared/numeric-parsers.js +1 -1
  294. package/dist/core/shared/option-alias-visibility.js +1 -1
  295. package/dist/core/shared/primitives.js +1 -1
  296. package/dist/core/shared/secret-rules.js +1 -1
  297. package/dist/core/shared/serial-queue.js +1 -1
  298. package/dist/core/shared/serialization.js +1 -1
  299. package/dist/core/shared/split-comma-list.js +1 -1
  300. package/dist/core/shared/text-normalization.js +1 -1
  301. package/dist/core/shared/time.js +2 -1
  302. package/dist/core/store/index.js +1 -1
  303. package/dist/core/store/item-format-migration.js +1 -1
  304. package/dist/core/store/item-metadata-cache.js +1 -1
  305. package/dist/core/store/item-metadata-query-index.js +7 -7
  306. package/dist/core/store/item-metadata-read-work.js +1 -1
  307. package/dist/core/store/item-store.js +1 -1
  308. package/dist/core/store/paths.js +1 -1
  309. package/dist/core/store/settings-concurrency.js +1 -1
  310. package/dist/core/store/settings-read-cache.js +1 -1
  311. package/dist/core/store/settings-validator.js +1 -1
  312. package/dist/core/store/settings.js +3 -3
  313. package/dist/core/store/tracker-preflight.js +1 -1
  314. package/dist/core/telemetry/consent.js +2 -2
  315. package/dist/core/telemetry/observability.js +1 -1
  316. package/dist/core/telemetry/policy.js +1 -1
  317. package/dist/core/telemetry/read-sampling.js +2 -2
  318. package/dist/core/telemetry/runtime.js +9 -5
  319. package/dist/core/test/background-runs.js +3 -3
  320. package/dist/core/test/item-test-run-tracking.js +1 -1
  321. package/dist/core/test/run-selectors.js +1 -1
  322. package/dist/core/validate/estimate-defaults.js +1 -1
  323. package/dist/core/validate/fix-planning.js +1 -1
  324. package/dist/core/validate/linked-artifact-reference.js +1 -1
  325. package/dist/core/validate/missing-by-type.js +1 -1
  326. package/dist/core/validate/missing-link-owners.js +1 -1
  327. package/dist/core/validate/stale-file-classification.js +1 -1
  328. package/dist/mcp/http-server.js +6 -4
  329. package/dist/mcp/legacy-adapter.js +1 -1
  330. package/dist/mcp/runtime-capabilities.js +1 -1
  331. package/dist/mcp/server.js +4 -4
  332. package/dist/mcp/tool-definitions.js +1 -1
  333. package/dist/sdk/actionability.js +1 -1
  334. package/dist/sdk/agent/closed-domain-contracts.js +1 -1
  335. package/dist/sdk/agent/command-recovery.js +1 -1
  336. package/dist/sdk/agent/command-suggestions.js +1 -1
  337. package/dist/sdk/agent/create-option-policy.js +1 -1
  338. package/dist/sdk/agent/identity-config.js +1 -1
  339. package/dist/sdk/agent/item-addressing.js +1 -1
  340. package/dist/sdk/agent/refusal-closure-census.js +2 -1
  341. package/dist/sdk/agent/refusal-closure.js +1 -1
  342. package/dist/sdk/agent/refusal-corpus-contracts.js +1 -1
  343. package/dist/sdk/agent/refusal-reachability.js +3 -1
  344. package/dist/sdk/agent/subcommand-recovery.js +1 -1
  345. package/dist/sdk/agent/task-transcript-contracts.js +1 -1
  346. package/dist/sdk/agent/tracker-preflight-contracts.js +1 -1
  347. package/dist/sdk/agent-capability-contracts.js +3 -1
  348. package/dist/sdk/agent-session-context.js +1 -1
  349. package/dist/sdk/annotations.js +1 -1
  350. package/dist/sdk/author-attribution.js +1 -1
  351. package/dist/sdk/authoring.js +1 -1
  352. package/dist/sdk/cli-bootstrap.d.ts +5 -1
  353. package/dist/sdk/cli-bootstrap.js +1 -1
  354. package/dist/sdk/cli-contracts/agent-output-contracts.js +5 -3
  355. package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -1
  356. package/dist/sdk/cli-contracts/command-aliases.js +1 -1
  357. package/dist/sdk/cli-contracts/command-exit-contracts.js +1 -1
  358. package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1
  359. package/dist/sdk/cli-contracts/commander-types.js +1 -1
  360. package/dist/sdk/cli-contracts/completeness.js +1 -1
  361. package/dist/sdk/cli-contracts/enum-contracts.js +1 -1
  362. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  363. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +2 -1
  364. package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
  365. package/dist/sdk/cli-contracts/registration-helpers.js +7 -7
  366. package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
  367. package/dist/sdk/cli-contracts/schemas/assurance-definition.js +1 -1
  368. package/dist/sdk/cli-contracts/string-lists.js +1 -1
  369. package/dist/sdk/cli-contracts/tool-option-contracts.js +1 -1
  370. package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
  371. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  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.d.ts +2 -0
  428. package/dist/sdk/extension/managed-state.js +2 -2
  429. package/dist/sdk/extension/managed-update-status.d.ts +3 -0
  430. package/dist/sdk/extension/managed-update-status.js +2 -0
  431. package/dist/sdk/extension/migrations.js +2 -2
  432. package/dist/sdk/extension/output-ownership.js +1 -1
  433. package/dist/sdk/extension/runtime-summary.js +1 -1
  434. package/dist/sdk/extension/scaffold.js +11 -4
  435. package/dist/sdk/extension/shared.js +1 -1
  436. package/dist/sdk/extension/source-resolution.d.ts +2 -6
  437. package/dist/sdk/extension/source-resolution.js +1 -1
  438. package/dist/sdk/extension/static-inventory.js +1 -1
  439. package/dist/sdk/extension/update-check.d.ts +10 -0
  440. package/dist/sdk/extension/update-check.js +1 -1
  441. package/dist/sdk/extension-command-context.js +2 -1
  442. package/dist/sdk/extension-contracts.js +1 -1
  443. package/dist/sdk/extension.d.ts +4 -0
  444. package/dist/sdk/extension.js +1 -1
  445. package/dist/sdk/files.js +1 -1
  446. package/dist/sdk/flag-invocation-contracts.js +1 -1
  447. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  448. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
  449. package/dist/sdk/generated-error-code-catalog.js +1 -1
  450. package/dist/sdk/governance/assurance-action-contracts.js +1 -1
  451. package/dist/sdk/governance/assurance-action.js +1 -1
  452. package/dist/sdk/governance/assurance-limits.js +1 -1
  453. package/dist/sdk/governance/assurance-mutation-error.js +1 -1
  454. package/dist/sdk/governance/assurance-presets.js +1 -1
  455. package/dist/sdk/governance/assurance-runtime.js +1 -1
  456. package/dist/sdk/governance/assurance.js +4 -4
  457. package/dist/sdk/governance/boundary-fixtures.js +1 -1
  458. package/dist/sdk/governance/closure-timestamps.js +1 -1
  459. package/dist/sdk/governance/coverage-assurance.js +1 -1
  460. package/dist/sdk/governance/defect-recurrence-coverage.js +1 -1
  461. package/dist/sdk/governance/defect-recurrence-graph.js +1 -1
  462. package/dist/sdk/governance/defect-recurrence-signals.js +1 -1
  463. package/dist/sdk/governance/defect-recurrence.js +1 -1
  464. package/dist/sdk/governance/extension-host-version.js +1 -1
  465. package/dist/sdk/governance/gc.js +1 -1
  466. package/dist/sdk/governance/health-merge-evidence.js +1 -1
  467. package/dist/sdk/governance/health.js +2 -1
  468. package/dist/sdk/governance/hierarchy-validation.js +1 -1
  469. package/dist/sdk/governance/linked-file-report.js +1 -1
  470. package/dist/sdk/governance/merge-receipt-history.js +1 -1
  471. package/dist/sdk/governance/provenance-health.js +4 -1
  472. package/dist/sdk/governance/reindex.js +5 -4
  473. package/dist/sdk/governance/stale-work.js +1 -1
  474. package/dist/sdk/governance/status-role-diagnostics.js +1 -1
  475. package/dist/sdk/governance/storage-integrity.js +1 -1
  476. package/dist/sdk/governance/tracked-runtime-cache.js +1 -1
  477. package/dist/sdk/governance/upgrade.js +2 -2
  478. package/dist/sdk/governance/validate-history-drift.js +1 -1
  479. package/dist/sdk/governance/validate-item-reader.js +1 -1
  480. package/dist/sdk/governance/validate-normalization.js +1 -1
  481. package/dist/sdk/governance/validate.js +1 -1
  482. package/dist/sdk/governance/workflow-completeness.js +1 -1
  483. package/dist/sdk/governance/workflow-policy.js +3 -3
  484. package/dist/sdk/governance/workspace-position.js +2 -1
  485. package/dist/sdk/governance.js +1 -1
  486. package/dist/sdk/graph/adapter.js +1 -1
  487. package/dist/sdk/graph/analytics.js +1 -1
  488. package/dist/sdk/graph/assembly.js +1 -1
  489. package/dist/sdk/graph/cache.js +1 -1
  490. package/dist/sdk/graph/centrality.js +1 -1
  491. package/dist/sdk/graph/conformance.js +1 -1
  492. package/dist/sdk/graph/deadline-scheduling.js +1 -1
  493. package/dist/sdk/graph/durable-cache.js +1 -1
  494. package/dist/sdk/graph/governance-contracts.js +1 -1
  495. package/dist/sdk/graph/governance.js +1 -1
  496. package/dist/sdk/graph/hierarchy-integrity.js +1 -1
  497. package/dist/sdk/graph/index.js +1 -1
  498. package/dist/sdk/graph/lifecycle-coverage.js +1 -1
  499. package/dist/sdk/graph/mutation-advisory.js +1 -1
  500. package/dist/sdk/graph/query-contracts.js +1 -1
  501. package/dist/sdk/graph/remediation.js +1 -1
  502. package/dist/sdk/graph/run.js +1 -1
  503. package/dist/sdk/graph/scheduling.js +1 -1
  504. package/dist/sdk/graph/traversal.js +1 -1
  505. package/dist/sdk/graph/workspace-relationship-kind-registry.js +1 -1
  506. package/dist/sdk/graph.js +1 -1
  507. package/dist/sdk/guide-topics.js +1 -1
  508. package/dist/sdk/guide.js +8 -1
  509. package/dist/sdk/history/attestation-command.js +1 -1
  510. package/dist/sdk/history/attestation-contract.js +1 -1
  511. package/dist/sdk/history/attestation-scan.js +1 -1
  512. package/dist/sdk/history/attestation.js +1 -1
  513. package/dist/sdk/history/maintenance.js +1 -1
  514. package/dist/sdk/history/salvage.js +3 -2
  515. package/dist/sdk/history/subject.js +1 -1
  516. package/dist/sdk/history-analytics.js +1 -1
  517. package/dist/sdk/history-compact.js +1 -1
  518. package/dist/sdk/history-mcp.js +1 -1
  519. package/dist/sdk/history-provenance.js +1 -1
  520. package/dist/sdk/history-read.js +1 -1
  521. package/dist/sdk/history-redact.js +1 -1
  522. package/dist/sdk/history-repair.js +1 -1
  523. package/dist/sdk/improvement-ledger-validation.js +1 -1
  524. package/dist/sdk/improvement-ledger.js +2 -2
  525. package/dist/sdk/index.js +1 -1
  526. package/dist/sdk/init-agent-guidance.js +16 -2
  527. package/dist/sdk/init.js +16 -2
  528. package/dist/sdk/invocation-author.js +1 -1
  529. package/dist/sdk/item-children.js +1 -1
  530. package/dist/sdk/item-metadata-index.js +1 -1
  531. package/dist/sdk/item-schedule.js +1 -1
  532. package/dist/sdk/item-transaction.js +1 -1
  533. package/dist/sdk/learnings.js +1 -1
  534. package/dist/sdk/lifecycle/append.js +4 -2
  535. package/dist/sdk/lifecycle/claim.js +1 -1
  536. package/dist/sdk/lifecycle/close-many.js +1 -1
  537. package/dist/sdk/lifecycle/close.js +1 -1
  538. package/dist/sdk/lifecycle/copy.js +1 -1
  539. package/dist/sdk/lifecycle/create.js +1 -1
  540. package/dist/sdk/lifecycle/delete.js +1 -1
  541. package/dist/sdk/lifecycle/event-validation-messages.js +1 -1
  542. package/dist/sdk/lifecycle/focus.js +1 -1
  543. package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +1 -1
  544. package/dist/sdk/lifecycle/legacy-none-tokens.js +1 -1
  545. package/dist/sdk/lifecycle/lifecycle-transitions.js +1 -1
  546. package/dist/sdk/lifecycle/mcp-actions.js +1 -1
  547. package/dist/sdk/lifecycle/metadata-normalizers.js +1 -1
  548. package/dist/sdk/lifecycle/mutation-command-options.js +1 -1
  549. package/dist/sdk/lifecycle/plan-mutation-receipt.js +1 -1
  550. package/dist/sdk/lifecycle/plan.js +1 -1
  551. package/dist/sdk/lifecycle/recurrence-parsers.js +1 -1
  552. package/dist/sdk/lifecycle/reopen.js +1 -1
  553. package/dist/sdk/lifecycle/repeatable-metadata-parsers.js +2 -1
  554. package/dist/sdk/lifecycle/restore.js +1 -1
  555. package/dist/sdk/lifecycle/shared-unset-fields.js +1 -1
  556. package/dist/sdk/lifecycle/task-composition.js +1 -1
  557. package/dist/sdk/lifecycle/update-many.js +1 -1
  558. package/dist/sdk/lifecycle/update.js +2 -1
  559. package/dist/sdk/lifecycle-completion.js +1 -1
  560. package/dist/sdk/lifecycle-policy.js +1 -1
  561. package/dist/sdk/linked-artifacts.js +2 -1
  562. package/dist/sdk/mcp/apps.js +1 -1
  563. package/dist/sdk/mcp/authorization.js +1 -1
  564. package/dist/sdk/mcp/discovery.js +1 -1
  565. package/dist/sdk/mcp/interactions.js +1 -1
  566. package/dist/sdk/mcp/protocol.js +1 -1
  567. package/dist/sdk/mcp/skills.js +3 -1
  568. package/dist/sdk/mcp/subscriptions.js +1 -1
  569. package/dist/sdk/mcp/tasks.js +2 -2
  570. package/dist/sdk/mcp/transport.js +1 -1
  571. package/dist/sdk/merge/abandoned-receipts.js +1 -1
  572. package/dist/sdk/merge/driver.js +1 -1
  573. package/dist/sdk/merge/index.js +1 -1
  574. package/dist/sdk/merge/install.js +4 -2
  575. package/dist/sdk/merge/receipt-file-boundary.js +1 -1
  576. package/dist/sdk/merge/receipt-operation.js +1 -1
  577. package/dist/sdk/merge/receipt-schema.js +1 -1
  578. package/dist/sdk/merge/receipts.js +4 -4
  579. package/dist/sdk/merge/reconcile.js +1 -1
  580. package/dist/sdk/merge/three-way.js +3 -2
  581. package/dist/sdk/merge/worktree-config.js +1 -1
  582. package/dist/sdk/merge.js +1 -1
  583. package/dist/sdk/mutation-events.js +1 -1
  584. package/dist/sdk/mutation-guard.js +1 -1
  585. package/dist/sdk/notes.js +1 -1
  586. package/dist/sdk/output-contracts.js +1 -1
  587. package/dist/sdk/output-projection.js +1 -1
  588. package/dist/sdk/output-token-accounting.js +1 -1
  589. package/dist/sdk/output.js +2 -1
  590. package/dist/sdk/ownership-source.js +1 -1
  591. package/dist/sdk/package-import-adapters.js +1 -1
  592. package/dist/sdk/package-migrations.js +1 -1
  593. package/dist/sdk/package-runtime-options.js +1 -1
  594. package/dist/sdk/pagination.js +1 -1
  595. package/dist/sdk/profile.js +5 -1
  596. package/dist/sdk/provenance.js +1 -1
  597. package/dist/sdk/public-surface.json +1 -1
  598. package/dist/sdk/query/activity.js +1 -1
  599. package/dist/sdk/query/aggregate.js +1 -1
  600. package/dist/sdk/query/calendar.js +4 -1
  601. package/dist/sdk/query/complete-list.js +1 -1
  602. package/dist/sdk/query/context.js +2 -1
  603. package/dist/sdk/query/duplicate-candidates.js +1 -1
  604. package/dist/sdk/query/get.d.ts +14 -2
  605. package/dist/sdk/query/get.js +1 -1
  606. package/dist/sdk/query/history.js +1 -1
  607. package/dist/sdk/query/item-filter-options.js +1 -1
  608. package/dist/sdk/query/light-metadata.js +1 -1
  609. package/dist/sdk/query/list-filter-shared.js +1 -1
  610. package/dist/sdk/query/list.js +1 -1
  611. package/dist/sdk/query/multi-value-filters.js +1 -1
  612. package/dist/sdk/query/next-ready-budget.js +1 -1
  613. package/dist/sdk/query/next.js +2 -1
  614. package/dist/sdk/query/parsers.js +1 -1
  615. package/dist/sdk/query/projection-contracts.js +1 -1
  616. package/dist/sdk/query/search/corpus.js +2 -1
  617. package/dist/sdk/query/search/filters.js +1 -1
  618. package/dist/sdk/query/search/input.js +1 -1
  619. package/dist/sdk/query/search/lexical.js +1 -1
  620. package/dist/sdk/query/search/response.js +1 -1
  621. package/dist/sdk/query/search/semantic.js +3 -2
  622. package/dist/sdk/query/search/types.js +1 -1
  623. package/dist/sdk/query/search-contracts.js +1 -1
  624. package/dist/sdk/query/search-pagination.js +1 -1
  625. package/dist/sdk/query/search-rendering.js +1 -1
  626. package/dist/sdk/query/search.js +1 -1
  627. package/dist/sdk/query/workspace-contracts.js +1 -1
  628. package/dist/sdk/query.js +1 -1
  629. package/dist/sdk/read-output/continuation.js +1 -1
  630. package/dist/sdk/read-output/options.js +1 -1
  631. package/dist/sdk/read-output/provenance.js +1 -1
  632. package/dist/sdk/read-output-budget.js +1 -1
  633. package/dist/sdk/read-output-contracts.js +1 -1
  634. package/dist/sdk/read-output-rows.js +1 -1
  635. package/dist/sdk/read-output-session.js +1 -1
  636. package/dist/sdk/relationship-analytics.js +1 -1
  637. package/dist/sdk/relationship-context.js +1 -1
  638. package/dist/sdk/relationship-history.js +7 -4
  639. package/dist/sdk/relationship-kinds/contract.js +1 -1
  640. package/dist/sdk/relationship-migration.js +1 -1
  641. package/dist/sdk/relationships.js +1 -1
  642. package/dist/sdk/reproducibility/process.js +1 -1
  643. package/dist/sdk/runtime/actions.js +1 -1
  644. package/dist/sdk/runtime/context.js +1 -1
  645. package/dist/sdk/runtime/schema-preview.js +1 -1
  646. package/dist/sdk/runtime/schema.js +1 -1
  647. package/dist/sdk/runtime-action-aliases.js +1 -1
  648. package/dist/sdk/runtime-extended-actions.js +1 -1
  649. package/dist/sdk/runtime-input.js +1 -1
  650. package/dist/sdk/runtime-primitives.js +1 -1
  651. package/dist/sdk/runtime-public-contracts.js +1 -1
  652. package/dist/sdk/runtime-stats-options.js +1 -1
  653. package/dist/sdk/runtime.js +1 -1
  654. package/dist/sdk/scheduling-shortcuts.js +1 -1
  655. package/dist/sdk/schema-migration.js +4 -3
  656. package/dist/sdk/schema.js +7 -1
  657. package/dist/sdk/search-refresh-worker.js +1 -1
  658. package/dist/sdk/similarity-scoring.js +1 -1
  659. package/dist/sdk/similarity.js +1 -1
  660. package/dist/sdk/start-task-status.js +1 -1
  661. package/dist/sdk/stats.js +1 -1
  662. package/dist/sdk/structured-mutations.js +1 -1
  663. package/dist/sdk/telemetry-flush.js +1 -1
  664. package/dist/sdk/telemetry.js +4 -3
  665. package/dist/sdk/templates.js +26 -2
  666. package/dist/sdk/test/batch.js +2 -2
  667. package/dist/sdk/test/entry.js +1 -1
  668. package/dist/sdk/test/execution.d.ts +2 -1
  669. package/dist/sdk/test/execution.js +6 -5
  670. package/dist/sdk/test/json-path.js +1 -1
  671. package/dist/sdk/test/linked-command-detection.js +1 -1
  672. package/dist/sdk/test/measurements.js +1 -1
  673. package/dist/sdk/test/parsers.js +1 -1
  674. package/dist/sdk/test/runs.js +1 -1
  675. package/dist/sdk/test/trust.js +2 -2
  676. package/dist/sdk/test/workspace-snapshot.js +1 -1
  677. package/dist/sdk/testing.js +7 -4
  678. package/dist/sdk/traceability/runtime-files-lookup.js +1 -1
  679. package/dist/sdk/traceability/source-traceability.js +2 -1
  680. package/dist/sdk/tracker-root-discovery.js +1 -1
  681. package/dist/sdk/workspace-contracts-cache.js +1 -1
  682. package/dist/sdk/workspace-contracts.js +1 -1
  683. package/dist/sdk/workspace-memory.js +2 -2
  684. package/dist/sdk/workspace-recipe.js +1 -1
  685. package/dist/sdk/workspace-snapshot.js +5 -4
  686. package/dist/sdk/workspace-transaction-gc.js +1 -1
  687. package/dist/sdk/workspace-transaction.js +2 -2
  688. package/dist/sdk/workspace.js +3 -2
  689. package/dist/types/index.js +1 -1
  690. package/dist/types.js +1 -1
  691. package/docs/AGENT_EVIDENCE_CONSISTENCY.md +88 -0
  692. package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +36 -0
  693. package/docs/GET_READ_EVIDENCE.md +84 -0
  694. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +23 -0
  695. package/docs/PR_REVIEW_LOOP.md +21 -4
  696. package/docs/README.md +3 -0
  697. package/docs/RELEASING.md +18 -0
  698. package/docs/SDK_CONFIGURATION_SAFETY.md +123 -0
  699. package/docs/generated/FLAG_LEXICON_BUDGETS.md +3 -3
  700. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
  701. package/marketplace.json +2 -2
  702. package/package.json +3 -3
  703. package/packages/pm-beads/package.json +1 -1
  704. package/packages/pm-calendar/package.json +1 -1
  705. package/packages/pm-command-kit/package.json +1 -1
  706. package/packages/pm-digital-twin/package.json +1 -1
  707. package/packages/pm-governance-audit/package.json +1 -1
  708. package/packages/pm-guide-shell/package.json +1 -1
  709. package/packages/pm-kanban/package.json +1 -1
  710. package/packages/pm-lifecycle-hooks/package.json +1 -1
  711. package/packages/pm-linked-test-adapters/package.json +1 -1
  712. package/packages/pm-search-advanced/package.json +1 -1
  713. package/packages/pm-templates/package.json +1 -1
  714. package/packages/pm-todos/package.json +1 -1
  715. package/packages/pm-vcs/extensions/vcs/index.ts +4 -2
  716. package/packages/pm-vcs/package.json +1 -1
  717. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  718. package/plugins/pm-claude/package.json +2 -2
  719. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  720. package/plugins/pm-codex/package.json +2 -2
  721. package/plugins/pm-codex/plugin.json +1 -1
  722. package/scripts/finalize-build.mjs +3 -2
  723. package/dist/cli-bundle/chunks/chunk-7UVXKI7K.js +0 -2
  724. package/dist/cli-bundle/chunks/chunk-D7Z2ZMJL.js +0 -3
  725. package/dist/cli-bundle/chunks/chunk-DEZPZOQ7.js +0 -2
  726. package/dist/cli-bundle/chunks/chunk-J52QIRRZ.js +0 -80
  727. package/dist/cli-bundle/chunks/chunk-JDKD3WGG.js +0 -6
  728. package/dist/cli-bundle/chunks/chunk-JQ7DW663.js +0 -2
  729. package/dist/cli-bundle/chunks/chunk-QXIDOOWT.js +0 -20
  730. package/dist/cli-bundle/chunks/chunk-SGFQQXFD.js +0 -2
  731. package/dist/cli-bundle/chunks/chunk-V3U77H3V.js +0 -31
  732. package/dist/cli-bundle/chunks/chunk-XZDWAYJC.js +0 -3
  733. package/dist/cli-bundle/chunks/chunk-Y6VRBTP3.js +0 -238
  734. package/dist/cli-bundle/chunks/chunk-YAAFYFS4.js +0 -8
  735. package/dist/cli-bundle/chunks/register-mutation-53ZLT4RX.js +0 -20
  736. package/dist/cli-bundle/chunks/register-operations-OBK2FXUU.js +0 -2
  737. package/dist/cli-bundle/chunks/register-setup-HM3OCBH2.js +0 -2
  738. package/dist/cli-bundle/focused-chunks/chunk-2JFYR56O.js +0 -2
  739. package/dist/cli-bundle/focused-chunks/chunk-32EVUSS4.js +0 -8
  740. package/dist/cli-bundle/focused-chunks/chunk-5GUSO2P4.js +0 -20
  741. package/dist/cli-bundle/focused-chunks/chunk-6XBRADQQ.js +0 -3
  742. package/dist/cli-bundle/focused-chunks/chunk-7O4NUJVO.js +0 -2
  743. package/dist/cli-bundle/focused-chunks/chunk-CURTIIQT.js +0 -2
  744. package/dist/cli-bundle/focused-chunks/chunk-IJUWEEEB.js +0 -6
  745. package/dist/cli-bundle/focused-chunks/chunk-JCVMOSWQ.js +0 -2
  746. package/dist/cli-bundle/focused-chunks/chunk-JMJK2L4Z.js +0 -3
  747. package/dist/cli-bundle/focused-chunks/chunk-KG3H4UZZ.js +0 -30
  748. package/dist/cli-bundle/focused-chunks/chunk-MHQ2XICU.js +0 -2
  749. package/dist/cli-bundle/focused-chunks/chunk-RJV6QVJE.js +0 -75
  750. package/dist/cli-bundle/focused-chunks/chunk-ZE2JZ7R6.js +0 -12
  751. package/dist/cli-bundle/focused-chunks/chunk-ZLEN4HZD.js +0 -165
@@ -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]="eeb9bc22-b9e1-5449-9ad0-fbb1a14fb09d")}catch(e2){}})();import{execFile}from"node:child_process";import{readFile}from"node:fs/promises";import path from"node:path";import{promisify}from"node:util";import{ensureDir,writeFileAtomic}from"../../core/fs/fs-utils.js";import{sha256Hex,stableStringify}from"../../core/shared/serialization.js";import{isTimestampLiteral}from"../../core/shared/time.js";import{getRuntimePath}from"../../core/store/paths.js";const execFileAsync=promisify(execFile);const LINKED_TEST_TRUST_LEDGER_VERSION=1;const LINKED_TEST_TRUST_LEDGER_FILE="linked-test-trust.json";function trustLedgerPath(pmRoot){return path.join(getRuntimePath(pmRoot),LINKED_TEST_TRUST_LEDGER_FILE)}function emptyTrustLedger(){return{version:LINKED_TEST_TRUST_LEDGER_VERSION,acknowledged:{}}}async function readTrustLedger(pmRoot){try{const parsed=JSON.parse(await readFile(trustLedgerPath(pmRoot),"utf8"));if(parsed.version!==LINKED_TEST_TRUST_LEDGER_VERSION||typeof parsed.acknowledged!=="object"||parsed.acknowledged===null||Array.isArray(parsed.acknowledged)){return emptyTrustLedger()}return{version:LINKED_TEST_TRUST_LEDGER_VERSION,acknowledged:parsed.acknowledged}}catch{return emptyTrustLedger()}}async function resolveLinkedTestSourceRef(cwd=process.cwd()){const hostedRef=process.env.GITHUB_HEAD_REF?.trim()||process.env.GITHUB_REF_NAME?.trim();if(hostedRef&&hostedRef!=="merge"){return hostedRef}try{const{stdout}=await execFileAsync("git",["symbolic-ref","--quiet","--short","HEAD"],{cwd,encoding:"utf8",windowsHide:true,timeout:1e4});const ref=stdout.trim();if(ref.length===0)return void 0;return ref}catch{return void 0}}function resolveLinkedTestSourceWorkspaceRoot(cwd=process.cwd()){return process.env.PM_SOURCE_WORKSPACE_ROOT?.trim()||cwd}function hasValidLinkedTestProvenance(provenance){if(provenance===null||typeof provenance!=="object")return false;return typeof provenance.author==="string"&&provenance.author.trim().length>0&&typeof provenance.created_at==="string"&&isTimestampLiteral(provenance.created_at)&&(provenance.source_kind==="local_mutation"||provenance.source_kind==="merge_union")}function linkedTestTrustRefs(sourceRef,currentSourceRef){return{...sourceRef?{source_ref:sourceRef}:{},...currentSourceRef?{current_source_ref:currentSourceRef}:{}}}function attachLinkedTestProvenance(tests,author,createdAt,sourceRef){return tests?.map(test=>test.command&&!test.provenance?{...test,provenance:{author,created_at:createdAt,source_kind:"local_mutation",...sourceRef?{source_ref:sourceRef}:{}}}:test)}async function attachLinkedTestMutationProvenance(tests,author,createdAt){if(!tests||tests.length===0)return tests;const sourceWorkspaceRoot=resolveLinkedTestSourceWorkspaceRoot();return attachLinkedTestProvenance(tests,author,createdAt,await resolveLinkedTestSourceRef(sourceWorkspaceRoot))}function linkedTestTrustFingerprint(test){return sha256Hex(stableStringify({command:test.command??null,path:test.path??null,scope:test.scope,pm_context_mode:test.pm_context_mode??null,workspace_context_mode:test.workspace_context_mode??null,env_set:test.env_set??null,env_clear:test.env_clear??null,shared_host_safe:test.shared_host_safe??null,provenance:test.provenance??null,provenance_invalid:test.provenance_invalid??null}))}async function resolveLinkedTestTrust(pmRoot,test,currentSourceRef){const ledger=await readTrustLedger(pmRoot);return resolveLinkedTestTrustFromLedger(test,currentSourceRef,ledger)}function resolveLinkedTestTrustFromLedger(test,currentSourceRef,ledger){const fingerprint=linkedTestTrustFingerprint(test);const sourceRef=test.provenance?.source_ref;if(test.provenance===void 0&&test.provenance_invalid!==true){return{fingerprint,trusted:true,reason:"legacy"}}const acknowledged=Object.hasOwn(ledger.acknowledged,fingerprint);if(test.provenance_invalid===true||!hasValidLinkedTestProvenance(test.provenance)){if(acknowledged){return{fingerprint,trusted:true,reason:"acknowledged",...linkedTestTrustRefs(void 0,currentSourceRef)}}return{fingerprint,trusted:false,reason:"invalid_provenance",...linkedTestTrustRefs(void 0,currentSourceRef)}}if(test.provenance.source_kind==="local_mutation"&&sourceRef===void 0){return{fingerprint,trusted:true,reason:"local_mutation",...linkedTestTrustRefs(void 0,currentSourceRef)}}if(test.provenance.source_kind==="local_mutation"&&sourceRef!==void 0&&sourceRef===currentSourceRef){return{fingerprint,trusted:true,reason:"local_source_ref",source_ref:sourceRef,current_source_ref:currentSourceRef}}if(acknowledged){return{fingerprint,trusted:true,reason:"acknowledged",...linkedTestTrustRefs(sourceRef,currentSourceRef)}}return{fingerprint,trusted:false,reason:"foreign_source_ref",...linkedTestTrustRefs(sourceRef,currentSourceRef)}}async function resolveLinkedTestTrustBatch(pmRoot,tests,currentSourceRef){const ledger=await readTrustLedger(pmRoot);return tests.map(test=>resolveLinkedTestTrustFromLedger(test,currentSourceRef,ledger))}async function acknowledgeLinkedTests(pmRoot,tests,acknowledgedAt){const ledger=await readTrustLedger(pmRoot);const fingerprints=tests.filter(test=>typeof test.command==="string"&&test.command.length>0).map(linkedTestTrustFingerprint);for(const fingerprint of fingerprints){ledger.acknowledged[fingerprint]={acknowledged_at:acknowledgedAt}}await ensureDir(path.dirname(trustLedgerPath(pmRoot)));await writeFileAtomic(trustLedgerPath(pmRoot),`${JSON.stringify(ledger,null,2)}
2
- `);return{acknowledged:fingerprints.length,fingerprints}}export{acknowledgeLinkedTests,attachLinkedTestMutationProvenance,attachLinkedTestProvenance,linkedTestTrustFingerprint,resolveLinkedTestSourceRef,resolveLinkedTestSourceWorkspaceRoot,resolveLinkedTestTrust,resolveLinkedTestTrustBatch};
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]="574bbc1f-493b-5c51-9c93-97234779a3ce")}catch{}})();import{execFile}from"node:child_process";import{readFile}from"node:fs/promises";import path from"node:path";import{promisify}from"node:util";import{ensureDir,writeFileAtomic}from"../../core/fs/fs-utils.js";import{sha256Hex,stableStringify}from"../../core/shared/serialization.js";import{isTimestampLiteral}from"../../core/shared/time.js";import{getRuntimePath}from"../../core/store/paths.js";const execFileAsync=promisify(execFile),LINKED_TEST_TRUST_LEDGER_VERSION=1,LINKED_TEST_TRUST_LEDGER_FILE="linked-test-trust.json";function trustLedgerPath(pmRoot){return path.join(getRuntimePath(pmRoot),LINKED_TEST_TRUST_LEDGER_FILE)}function emptyTrustLedger(){return{version:LINKED_TEST_TRUST_LEDGER_VERSION,acknowledged:{}}}async function readTrustLedger(pmRoot){try{const parsed=JSON.parse(await readFile(trustLedgerPath(pmRoot),"utf8"));return parsed.version!==LINKED_TEST_TRUST_LEDGER_VERSION||typeof parsed.acknowledged!="object"||parsed.acknowledged===null||Array.isArray(parsed.acknowledged)?emptyTrustLedger():{version:LINKED_TEST_TRUST_LEDGER_VERSION,acknowledged:parsed.acknowledged}}catch{return emptyTrustLedger()}}async function resolveLinkedTestSourceRef(cwd=process.cwd()){const hostedRef=process.env.GITHUB_HEAD_REF?.trim()||process.env.GITHUB_REF_NAME?.trim();if(hostedRef&&hostedRef!=="merge")return hostedRef;try{const{stdout}=await execFileAsync("git",["symbolic-ref","--quiet","--short","HEAD"],{cwd,encoding:"utf8",windowsHide:!0,timeout:1e4}),ref=stdout.trim();return ref.length===0?void 0:ref}catch{return}}function resolveLinkedTestSourceWorkspaceRoot(cwd=process.cwd()){return process.env.PM_SOURCE_WORKSPACE_ROOT?.trim()||cwd}function hasValidLinkedTestProvenance(provenance){return provenance===null||typeof provenance!="object"?!1:typeof provenance.author=="string"&&provenance.author.trim().length>0&&typeof provenance.created_at=="string"&&isTimestampLiteral(provenance.created_at)&&(provenance.source_kind==="local_mutation"||provenance.source_kind==="merge_union")}function linkedTestTrustRefs(sourceRef,currentSourceRef){return{...sourceRef?{source_ref:sourceRef}:{},...currentSourceRef?{current_source_ref:currentSourceRef}:{}}}function attachLinkedTestProvenance(tests,author,createdAt,sourceRef){return tests?.map(test=>test.command&&!test.provenance?{...test,provenance:{author,created_at:createdAt,source_kind:"local_mutation",...sourceRef?{source_ref:sourceRef}:{}}}:test)}async function attachLinkedTestMutationProvenance(tests,author,createdAt){if(!tests||tests.length===0)return tests;const sourceWorkspaceRoot=resolveLinkedTestSourceWorkspaceRoot();return attachLinkedTestProvenance(tests,author,createdAt,await resolveLinkedTestSourceRef(sourceWorkspaceRoot))}function linkedTestTrustFingerprint(test){return sha256Hex(stableStringify({command:test.command??null,path:test.path??null,scope:test.scope,pm_context_mode:test.pm_context_mode??null,workspace_context_mode:test.workspace_context_mode??null,env_set:test.env_set??null,env_clear:test.env_clear??null,shared_host_safe:test.shared_host_safe??null,provenance:test.provenance??null,provenance_invalid:test.provenance_invalid??null}))}async function resolveLinkedTestTrust(pmRoot,test,currentSourceRef){const ledger=await readTrustLedger(pmRoot);return resolveLinkedTestTrustFromLedger(test,currentSourceRef,ledger)}function resolveLinkedTestTrustFromLedger(test,currentSourceRef,ledger){const fingerprint=linkedTestTrustFingerprint(test),sourceRef=test.provenance?.source_ref;if(test.provenance===void 0&&test.provenance_invalid!==!0)return{fingerprint,trusted:!0,reason:"legacy"};const acknowledged=Object.hasOwn(ledger.acknowledged,fingerprint);return test.provenance_invalid===!0||!hasValidLinkedTestProvenance(test.provenance)?acknowledged?{fingerprint,trusted:!0,reason:"acknowledged",...linkedTestTrustRefs(void 0,currentSourceRef)}:{fingerprint,trusted:!1,reason:"invalid_provenance",...linkedTestTrustRefs(void 0,currentSourceRef)}:test.provenance.source_kind==="local_mutation"&&sourceRef===void 0?{fingerprint,trusted:!0,reason:"local_mutation",...linkedTestTrustRefs(void 0,currentSourceRef)}:test.provenance.source_kind==="local_mutation"&&sourceRef!==void 0&&sourceRef===currentSourceRef?{fingerprint,trusted:!0,reason:"local_source_ref",source_ref:sourceRef,current_source_ref:currentSourceRef}:acknowledged?{fingerprint,trusted:!0,reason:"acknowledged",...linkedTestTrustRefs(sourceRef,currentSourceRef)}:{fingerprint,trusted:!1,reason:"foreign_source_ref",...linkedTestTrustRefs(sourceRef,currentSourceRef)}}async function resolveLinkedTestTrustBatch(pmRoot,tests,currentSourceRef){const ledger=await readTrustLedger(pmRoot);return tests.map(test=>resolveLinkedTestTrustFromLedger(test,currentSourceRef,ledger))}async function acknowledgeLinkedTests(pmRoot,tests,acknowledgedAt){const ledger=await readTrustLedger(pmRoot),fingerprints=tests.filter(test=>typeof test.command=="string"&&test.command.length>0).map(linkedTestTrustFingerprint);for(const fingerprint of fingerprints)ledger.acknowledged[fingerprint]={acknowledged_at:acknowledgedAt};return await ensureDir(path.dirname(trustLedgerPath(pmRoot))),await writeFileAtomic(trustLedgerPath(pmRoot),`${JSON.stringify(ledger,null,2)}
2
+ `),{acknowledged:fingerprints.length,fingerprints}}export{acknowledgeLinkedTests,attachLinkedTestMutationProvenance,attachLinkedTestProvenance,linkedTestTrustFingerprint,resolveLinkedTestSourceRef,resolveLinkedTestSourceWorkspaceRoot,resolveLinkedTestTrust,resolveLinkedTestTrustBatch};
3
3
  //# sourceMappingURL=trust.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]="50a9baf9-931e-5822-a71a-122398a94b8c")}catch(e2){}})();import{cp,lstat,mkdir,readlink,realpath,stat,symlink}from"node:fs/promises";import path from"node:path";import{isFileMissingError}from"../../core/fs/fs-utils.js";const EXCLUDED_SEGMENTS=new Set([".agents",".git",".nyc_output",".turbo","coverage"]);function hasExcludedSegment(relative){return relative.split(path.sep).some(segment=>EXCLUDED_SEGMENTS.has(segment.toLowerCase()))}function isOutsideWorkspace(relative){return relative===".."||relative.startsWith(`..${path.sep}`)||path.isAbsolute(relative)}async function statSnapshotTarget(source){try{return await stat(source)}catch(error){if(!isFileMissingError(error))throw error;return void 0}}async function resolveLinkTarget(target){const missing=[];let ancestor=target;while(path.dirname(ancestor)!==ancestor){try{return path.join(await realpath(ancestor),...missing)}catch(error){if(!isFileMissingError(error))throw error;missing.unshift(path.basename(ancestor));ancestor=path.dirname(ancestor)}}return path.join(await realpath(ancestor),...missing)}async function resolveSnapshotTarget(target,sourceRoot,dependencyRoots){const relative=path.relative(sourceRoot,await resolveLinkTarget(target));if(!isOutsideWorkspace(relative))return relative;const suffix=[];let ancestor=target;while(path.dirname(ancestor)!==ancestor){const physicalAncestor=await resolveLinkTarget(ancestor);const dependency=dependencyRoots.find(([,root])=>root===physicalAncestor);if(dependency)return path.join(dependency[0],...suffix);suffix.unshift(path.basename(ancestor));ancestor=path.dirname(ancestor)}return relative}async function seedLinkedTestWorkspaceSnapshot(sourceRoot,snapshotRoot){const dependencyRoots=[];const sourceLinks=[];const resolvedSourceRoot=await realpath(sourceRoot);const resolvedSnapshotRoot=await resolveLinkTarget(path.resolve(snapshotRoot));if(![path.relative(resolvedSourceRoot,resolvedSnapshotRoot),path.relative(resolvedSnapshotRoot,resolvedSourceRoot)].every(isOutsideWorkspace)){throw new Error("Snapshot destination must be disjoint from the source workspace; choose a temporary root outside the checkout.")}await mkdir(path.dirname(snapshotRoot),{recursive:true});await cp(resolvedSourceRoot,snapshotRoot,{recursive:true,force:true,async filter(source){const relative=path.relative(resolvedSourceRoot,source);if(!relative)return true;if(hasExcludedSegment(relative))return false;if(path.basename(source).toLowerCase()==="node_modules"){if((await statSnapshotTarget(source))?.isDirectory()){const target=await resolveLinkTarget(source);const targetRelative=path.relative(resolvedSourceRoot,target);if(!isOutsideWorkspace(path.relative(target,resolvedSourceRoot))||!isOutsideWorkspace(targetRelative)&&(hasExcludedSegment(targetRelative)||!targetRelative.split(path.sep).some(segment=>segment.toLowerCase()==="node_modules"))){throw new Error(`Dependency symlink must target an included dependency directory or external installation: ${relative}`)}dependencyRoots.push([relative,target])}return false}if(!(await lstat(source)).isSymbolicLink())return true;sourceLinks.push([relative,path.resolve(path.dirname(source),await readlink(source)),(await statSnapshotTarget(source))?.isDirectory()?"junction":"file"]);return false}});for(const[relative]of dependencyRoots){await symlink(path.resolve(resolvedSourceRoot,relative),path.join(snapshotRoot,relative),"junction")}for(const[relative,target,type]of sourceLinks){const targetRelative=await resolveSnapshotTarget(target,resolvedSourceRoot,dependencyRoots);if(isOutsideWorkspace(targetRelative)||hasExcludedSegment(targetRelative)){throw new Error(`Source symlink must target included workspace source: ${relative}`)}await symlink(path.resolve(snapshotRoot,targetRelative),path.join(snapshotRoot,relative),type)}}export{seedLinkedTestWorkspaceSnapshot};
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]="d27093d8-5bac-5dcf-8334-07c8b8bc93a7")}catch{}})();import{cp,lstat,mkdir,readlink,realpath,stat,symlink}from"node:fs/promises";import path from"node:path";import{isFileMissingError}from"../../core/fs/fs-utils.js";const EXCLUDED_SEGMENTS=new Set([".agents",".git",".nyc_output",".turbo","coverage"]);function hasExcludedSegment(relative){return relative.split(path.sep).some(segment=>EXCLUDED_SEGMENTS.has(segment.toLowerCase()))}function isOutsideWorkspace(relative){return relative===".."||relative.startsWith(`..${path.sep}`)||path.isAbsolute(relative)}async function statSnapshotTarget(source){try{return await stat(source)}catch(error){if(!isFileMissingError(error))throw error;return}}async function resolveLinkTarget(target){const missing=[];let ancestor=target;for(;path.dirname(ancestor)!==ancestor;)try{return path.join(await realpath(ancestor),...missing)}catch(error){if(!isFileMissingError(error))throw error;missing.unshift(path.basename(ancestor)),ancestor=path.dirname(ancestor)}return path.join(await realpath(ancestor),...missing)}async function resolveSnapshotTarget(target,sourceRoot,dependencyRoots){const relative=path.relative(sourceRoot,await resolveLinkTarget(target));if(!isOutsideWorkspace(relative))return relative;const suffix=[];let ancestor=target;for(;path.dirname(ancestor)!==ancestor;){const physicalAncestor=await resolveLinkTarget(ancestor),dependency=dependencyRoots.find(([,root])=>root===physicalAncestor);if(dependency)return path.join(dependency[0],...suffix);suffix.unshift(path.basename(ancestor)),ancestor=path.dirname(ancestor)}return relative}async function seedLinkedTestWorkspaceSnapshot(sourceRoot,snapshotRoot){const dependencyRoots=[],sourceLinks=[],resolvedSourceRoot=await realpath(sourceRoot),resolvedSnapshotRoot=await resolveLinkTarget(path.resolve(snapshotRoot));if(![path.relative(resolvedSourceRoot,resolvedSnapshotRoot),path.relative(resolvedSnapshotRoot,resolvedSourceRoot)].every(isOutsideWorkspace))throw new Error("Snapshot destination must be disjoint from the source workspace; choose a temporary root outside the checkout.");await mkdir(path.dirname(snapshotRoot),{recursive:!0}),await cp(resolvedSourceRoot,snapshotRoot,{recursive:!0,force:!0,async filter(source){const relative=path.relative(resolvedSourceRoot,source);if(!relative)return!0;if(hasExcludedSegment(relative))return!1;if(path.basename(source).toLowerCase()==="node_modules"){if((await statSnapshotTarget(source))?.isDirectory()){const target=await resolveLinkTarget(source),targetRelative=path.relative(resolvedSourceRoot,target);if(!isOutsideWorkspace(path.relative(target,resolvedSourceRoot))||!isOutsideWorkspace(targetRelative)&&(hasExcludedSegment(targetRelative)||!targetRelative.split(path.sep).some(segment=>segment.toLowerCase()==="node_modules")))throw new Error(`Dependency symlink must target an included dependency directory or external installation: ${relative}`);dependencyRoots.push([relative,target])}return!1}return(await lstat(source)).isSymbolicLink()?(sourceLinks.push([relative,path.resolve(path.dirname(source),await readlink(source)),(await statSnapshotTarget(source))?.isDirectory()?"junction":"file"]),!1):!0}});for(const[relative]of dependencyRoots)await symlink(path.resolve(resolvedSourceRoot,relative),path.join(snapshotRoot,relative),"junction");for(const[relative,target,type]of sourceLinks){const targetRelative=await resolveSnapshotTarget(target,resolvedSourceRoot,dependencyRoots);if(isOutsideWorkspace(targetRelative)||hasExcludedSegment(targetRelative))throw new Error(`Source symlink must target included workspace source: ${relative}`);await symlink(path.resolve(snapshotRoot,targetRelative),path.join(snapshotRoot,relative),type)}}export{seedLinkedTestWorkspaceSnapshot};
2
2
  //# sourceMappingURL=workspace-snapshot.js.map
@@ -1,5 +1,8 @@
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]="52ee6b9f-9465-52ec-9164-c5b21360d078")}catch(e2){}})();import{activateExtensions,deactivateExtensions,runAfterCommandHooks,runBeforeCommandHooks,runBeforeMutationHooks,runCommandHandler,runCommandOverride,runOnIndexHooks,runOnReadHooks,runOnWriteHooks,runParserOverride,runPreflightOverride,runRendererOverride,runServiceOverride}from"../core/extensions/loader.js";import{createDefaultExtensionGovernancePolicy}from"../core/extensions/extension-types.js";import{getMigrationRuntimeDefinition,resolveRegisteredSearchProvider,resolveRegisteredVectorStoreAdapter}from"../core/extensions/runtime-registrations.js";import{collectUsedExtensionCapabilities}from"../core/extensions/capability-usage.js";import{normalizeKnownExtensionCapability}from"../core/extensions/extension-capability-aliases.js";import{checkExtensionManifestCompatibility,describeExtensionBlueprint,lintExtensionBlueprint,preflightExtension}from"./compose.js";import{describeExtensionActivation}from"../core/extensions/activation-summary.js";import{lintProjectProfile}from"../core/profile/profile-lint.js";import{renderExtensionSurfaceMarkdown}from"../core/extensions/activation-summary-markdown.js";import{asPropertyRecord,resolveActivatablePropertyRecord}from"../core/shared/primitives.js";import{createExtensionCommandSdk}from"./extension-command-context.js";import{PmClient}from"./runtime.js";function registeredExpectationName(expectation,legacyValue){return expectation.name??legacyValue??""}const HOOK_KIND_TO_REGISTRY_FIELD={before_command:"beforeCommand",before_mutation:"beforeMutation",after_command:"afterCommand",on_read:"onRead",on_write:"onWrite",on_index:"onIndex"};const RUNNABLE_HOOK_KIND_TO_REGISTRY_FIELD={before_command:"beforeCommand",after_command:"afterCommand",on_read:"onRead",on_write:"onWrite",on_index:"onIndex"};function normalizeSdkIdentifier(value){return value.trim().toLowerCase()}function normalizeSdkProfileMatchKey(value){return normalizeSdkIdentifier(value).replaceAll("-","_")}function extensionNameSuffix(extensionName){return extensionName?` from extension "${extensionName}"`:""}function sortedUnique(values){return[...new Set(values)].sort((left,right)=>left.localeCompare(right))}function normalizeSdkCommandName(command){if(typeof command!=="string"){throw new Error('A command name string is required. Pass it via the options object, e.g. runRegisteredCommandForTest(activation, { command: "my command" }) \u2014 positional command arguments are not supported.')}return command.trim().toLowerCase().split(/\s+/).filter(part=>part.length>0).join(" ")}function formatAvailable(values){return values.length>0?values.join(", "):"(none)"}function assertStringSetIncludes(actual,expected,label){const actualValues=new Set(actual??[]);const missing=sortedUnique(expected.filter(value=>!actualValues.has(value)));if(missing.length>0){throw new Error(`Expected package manifest ${label} to include ${missing.join(", ")}; available: ${formatAvailable(sortedUnique(actual??[]))}`)}}function collectFlagLabels(flags){const labels=new Set;for(const flag of flags){if(typeof flag.long==="string"&&flag.long.trim().length>0){labels.add(flag.long.trim())}if(typeof flag.short==="string"&&flag.short.trim().length>0){labels.add(flag.short.trim())}}return labels}function readTestExtensionManifest(module){const moduleRecord=asPropertyRecord(module);if(!moduleRecord){return{}}const manifest=asPropertyRecord(moduleRecord.manifest);if(manifest){return manifest}const defaultExport=asPropertyRecord(moduleRecord.default);const defaultManifest=asPropertyRecord(defaultExport?.manifest);if(defaultManifest){return defaultManifest}if(defaultExport&&typeof moduleRecord.default!=="function"&&("name"in defaultExport||"capabilities"in defaultExport)){return defaultExport}if(typeof module!=="function"&&("name"in moduleRecord||"capabilities"in moduleRecord)){return moduleRecord}return{}}function resolveTestExtensionName(manifest,explicitName){return explicitName??(typeof manifest.name==="string"&&manifest.name.trim().length>0?manifest.name.trim():"test-extension")}function readTestExtensionCapabilities(manifest,options){if(Array.isArray(options.capabilities)){return[...options.capabilities]}if(Array.isArray(manifest.capabilities)){return manifest.capabilities.filter(capability=>typeof capability==="string")}return[]}function buildSingleExtensionLoadResult(module,manifest,identity){return{disabled_by_flag:false,roots:{global:"",project:""},configured_enabled:[],configured_disabled:[],discovered:[],effective:[],warnings:[],policy:identity.policy,failed:[],loaded:[{layer:identity.layer,directory:"",manifest_path:"",name:identity.name,version:typeof manifest.version==="string"?manifest.version:"0.0.0",entry:typeof manifest.entry==="string"?manifest.entry:"./index.js",priority:typeof manifest.priority==="number"?manifest.priority:0,entry_path:"",capabilities:identity.capabilities,manifest_version:typeof manifest.manifest_version==="number"?manifest.manifest_version:void 0,pm_min_version:typeof manifest.pm_min_version==="string"?manifest.pm_min_version:void 0,pm_max_version:typeof manifest.pm_max_version==="string"?manifest.pm_max_version:void 0,engines:manifest.engines,trusted:manifest.trusted,provenance:manifest.provenance,sandbox_profile:manifest.sandbox_profile,permissions:manifest.permissions,activation:manifest.activation,module}]}}async function activateExtensionForTest(module,options={}){const manifest=readTestExtensionManifest(module);return activateExtensions(buildSingleExtensionLoadResult(module,manifest,{name:resolveTestExtensionName(manifest,options.name),layer:options.layer??"project",capabilities:readTestExtensionCapabilities(manifest,options),policy:options.policy??createDefaultExtensionGovernancePolicy()}))}async function deactivateExtensionForTest(module,options={}){const manifest=readTestExtensionManifest(module);return deactivateExtensions(buildSingleExtensionLoadResult(module,manifest,{name:resolveTestExtensionName(manifest,options.name),layer:options.layer??"project",capabilities:readTestExtensionCapabilities(manifest,{}),policy:createDefaultExtensionGovernancePolicy()}),options.activation,options.deactivateTimeoutMs===void 0?{}:{deactivate_timeout_ms:options.deactivateTimeoutMs})}async function runRegisteredCommandForTest(commands,options){const command=normalizeSdkCommandName(options.command);if(command.length===0){throw new Error("Expected command name must be a non-empty string")}const hasHandler=commands.handlers.some(entry=>entry.command===command);if(!hasHandler){const available=sortedUnique(commands.handlers.map(entry=>entry.command));throw new Error(`Expected a registered command handler for "${command}" to invoke. Available command handlers: ${formatAvailable(available)}`)}if(options.sdk!==void 0&&options.sdkFactory!==void 0){throw new TypeError("runRegisteredCommandForTest accepts sdk or sdkFactory, not both")}const pmRoot=options.pmRoot??"";const global2={json:true,quiet:true,noPager:true,...options.global};const sdk=options.sdk??options.sdkFactory?.({pmRoot,global:global2})??(pmRoot.length>0?createExtensionCommandSdk(pmRoot,new PmClient({pmRoot}),void 0,command):void 0);return runCommandHandler(commands,{command,args:options.args?[...options.args]:[],options:options.options?{...options.options}:{},global:global2,pm_root:pmRoot,...sdk===void 0?{}:{sdk}})}async function runRegisteredMutationGuardForTest(hooks,options){if((hooks.beforeMutation?.length??0)===0){throw new Error("Expected a registered before_mutation hook to invoke")}await runBeforeMutationHooks(hooks,options.context)}async function runRegisteredHookForTest(hooks,options){const kind=options.kind;if(kind==="before_mutation"){throw new Error("Invoke before_mutation hooks with runRegisteredMutationGuardForTest so denials and failures retain fail-closed semantics.")}if((hooks[RUNNABLE_HOOK_KIND_TO_REGISTRY_FIELD[kind]]?.length??0)===0){const populatedKinds=sortedUnique(Object.keys(RUNNABLE_HOOK_KIND_TO_REGISTRY_FIELD).filter(candidateKind=>(hooks[RUNNABLE_HOOK_KIND_TO_REGISTRY_FIELD[candidateKind]]?.length??0)>0));throw new Error(`Expected a registered "${kind}" hook to invoke. Hook kinds with registrations: ${formatAvailable(populatedKinds)}`)}switch(options.kind){case"before_command":return runBeforeCommandHooks(hooks,options.context);case"after_command":return runAfterCommandHooks(hooks,options.context);case"on_read":return runOnReadHooks(hooks,options.context);case"on_write":return runOnWriteHooks(hooks,options.context);case"on_index":return runOnIndexHooks(hooks,options.context)}}async function runRegisteredParserOverrideForTest(parsers,context){const command=normalizeSdkCommandName(context.command);if(!parsers.overrides.some(entry=>entry.command===command)){throw new Error(`Expected a registered parser override for command "${command}" to invoke. Available parser override commands: ${formatAvailable(sortedUnique(parsers.overrides.map(entry=>entry.command)))}`)}return runParserOverride(parsers,context)}async function runRegisteredPreflightOverrideForTest(preflight,context){if(preflight.overrides.length===0){throw new Error("Expected a registered preflight override to invoke, but none are registered.")}return runPreflightOverride(preflight,context)}async function runRegisteredCommandOverrideForTest(commands,context){const command=normalizeSdkCommandName(context.command);if(!commands.overrides.some(entry=>entry.command===command)){throw new Error(`Expected a registered command override for command "${command}" to invoke. Available command override commands: ${formatAvailable(sortedUnique(commands.overrides.map(entry=>entry.command)))}`)}return runCommandOverride(commands,context)}async function runRegisteredRendererOverrideForTest(renderers,context){if(!renderers.overrides.some(entry=>entry.format===context.format)){throw new Error(`Expected a registered renderer override for format "${context.format}" to invoke. Available renderer override formats: ${formatAvailable(sortedUnique(renderers.overrides.map(entry=>entry.format)))}`)}return runRendererOverride(renderers,context)}async function runRegisteredServiceOverrideForTest(services,context){if(!services.overrides.some(entry=>entry.service===context.service)){throw new Error(`Expected a registered service override for service "${context.service}" to invoke. Available service override services: ${formatAvailable(sortedUnique(services.overrides.map(entry=>entry.service)))}`)}return runServiceOverride(services,context)}const SEARCH_PROVIDER_OPERATION_DEFINITION_KEYS={query:["query"],embed:["embed"],embedBatch:["embedBatch","embed_batch"],queryExpansion:["queryExpansion","query_expansion"],rerank:["rerank"]};async function runRegisteredSearchProviderForTest(registrations,options){const registration=resolveRegisteredSearchProvider(registrations,options.provider);if(!registration){const available=sortedUnique(registrations.search_providers.map(entry=>entry.definition.name));throw new Error(`Expected a registered search provider "${options.provider}" to invoke. Available search providers: ${formatAvailable(available)}`)}const runtimeDefinition=registration.runtime_definition;const operationFn=SEARCH_PROVIDER_OPERATION_DEFINITION_KEYS[options.operation].map(key=>runtimeDefinition[key]).find(value=>typeof value==="function");if(typeof operationFn!=="function"){throw new Error(`Registered search provider "${options.provider}" does not implement the "${options.operation}" operation.`)}return await operationFn(options.context)}async function runRegisteredVectorStoreAdapterForTest(registrations,options){const registration=resolveRegisteredVectorStoreAdapter(registrations,options.adapter);if(!registration){const available=sortedUnique(registrations.vector_store_adapters.map(entry=>entry.definition.name));throw new Error(`Expected a registered vector store adapter "${options.adapter}" to invoke. Available vector store adapters: ${formatAvailable(available)}`)}const operationFn=registration.runtime_definition[options.operation];if(typeof operationFn!=="function"){throw new Error(`Registered vector store adapter "${options.adapter}" does not implement the "${options.operation}" operation.`)}return await operationFn(options.context)}async function runRegisteredMigrationForTest(registrations,options){const migration=assertRegisteredMigration(registrations,{migration:options.migration,extensionName:options.extensionName});const run=getMigrationRuntimeDefinition(migration).run;if(typeof run!=="function"){throw new Error(`Registered migration "${options.migration}" does not implement a run function to invoke.`)}const declaredStatus=migration.definition.status;const context={id:migration.definition.id,command:"migration",layer:migration.layer,extension:migration.name,pm_root:options.pmRoot??"",status:(typeof declaredStatus==="string"?declaredStatus.trim().toLowerCase():"")||"pending"};return await run(context)}async function runRegisteredImporterForTest(activation,options){const importer=assertRegisteredImporter(activation.registrations,{importer:options.importer,extensionName:options.extensionName});return runRegisteredCommandForTest(activation.commands,{command:`${importer.importer} import`,args:options.args,options:options.options,global:options.global,pmRoot:options.pmRoot})}async function runRegisteredExporterForTest(activation,options){const exporter=assertRegisteredExporter(activation.registrations,{exporter:options.exporter,extensionName:options.extensionName});return runRegisteredCommandForTest(activation.commands,{command:`${exporter.exporter} export`,args:options.args,options:options.options,global:options.global,pmRoot:options.pmRoot})}function assertExtensionDeactivated(result,expectation={}){const expectedDeactivated=expectation.deactivated??1;if(result.deactivated!==expectedDeactivated){throw new Error(`Expected ${expectedDeactivated} extension${expectedDeactivated===1?"":"s"} to deactivate cleanly, but ${result.deactivated} did.`)}const expectedFailed=expectation.failed??0;if(result.failed.length!==expectedFailed){const detail=result.failed.map(failure=>`${failure.layer}:${failure.name} (${failure.error})`).join(", ");throw new Error(`Expected ${expectedFailed} teardown failure${expectedFailed===1?"":"s"}, but observed ${result.failed.length}${detail.length>0?`: ${detail}`:""}.`)}return result}function assertPackageManifest(manifest,expectation){if(expectation.packageName!==void 0&&manifest.package_name!==expectation.packageName){throw new Error(`Expected package manifest package_name to be "${expectation.packageName}"; received "${manifest.package_name??"(none)"}"`)}if(expectation.aliases!==void 0){assertStringSetIncludes(manifest.aliases,expectation.aliases,"aliases")}if(expectation.resources!==void 0){for(const[kind,expectedPaths]of Object.entries(expectation.resources)){assertStringSetIncludes(manifest.resources[kind],expectedPaths,`pm.${kind}`)}}return manifest}function assertRegisteredCommandContract(registrations,expectation){const expectedCommand=normalizeSdkCommandName(registeredExpectationName(expectation,expectation.command));if(expectedCommand.length===0){throw new Error("Expected command name must be a non-empty string")}const commandCandidates=registrations.commands.filter(entry=>entry.command===expectedCommand);const command=expectation.extensionName?commandCandidates.find(entry=>entry.name===expectation.extensionName):commandCandidates[0];if(!command){const available=registrations.commands.map(entry=>entry.command).sort((left,right)=>left.localeCompare(right));const extensionSuffix=expectation.extensionName?` from extension "${expectation.extensionName}"`:"";throw new Error(`Expected extension command "${expectedCommand}"${extensionSuffix} to be registered. Available commands: ${formatAvailable(available)}`)}if(expectation.action!==void 0&&command.action!==expectation.action){throw new Error(`Expected extension command "${expectedCommand}" action "${expectation.action}", received "${command.action}"`)}if(expectation.arguments!==void 0){const actualArguments=(command.arguments??[]).map(argument=>argument.name);const missingArguments=expectation.arguments.filter(argument=>!actualArguments.includes(argument));if(missingArguments.length>0){throw new Error(`Expected extension command "${expectedCommand}" arguments ${formatAvailable(expectation.arguments)}; missing ${formatAvailable(missingArguments)}; available ${formatAvailable(actualArguments)}`)}}const flags=registrations.flags.filter(entry=>entry.target_command===expectedCommand&&(expectation.extensionName===void 0||entry.name===expectation.extensionName)).flatMap(entry=>entry.flags);if(expectation.flags!==void 0){const actualFlagLabels=collectFlagLabels(flags);const missingFlags=expectation.flags.filter(flag=>!actualFlagLabels.has(flag));if(missingFlags.length>0){throw new Error(`Expected extension command "${expectedCommand}" flags ${formatAvailable(expectation.flags)}; missing ${formatAvailable(missingFlags)}; available ${formatAvailable([...actualFlagLabels].sort((left,right)=>left.localeCompare(right)))}`)}}return{command,flags}}function assertRegisteredFlags(registrations,expectation){const expectedCommand=normalizeSdkCommandName(registeredExpectationName(expectation,expectation.targetCommand));if(expectedCommand.length===0){throw new Error("Expected target command name must be a non-empty string")}const candidates=registrations.flags.filter(entry=>entry.target_command===expectedCommand);let registration;if(expectation.extensionName){registration=candidates.find(entry=>entry.name===expectation.extensionName)}else if(candidates.length===1){registration=candidates[0]}else if(candidates.length>1){const availableExtensions=sortedUnique(candidates.map(entry=>entry.name));throw new Error(`Expected flags for target command "${expectedCommand}" matched multiple extensions: ${formatAvailable(availableExtensions)}. Specify extensionName to choose one registration.`)}if(!registration){const available=sortedUnique(registrations.flags.map(entry=>entry.target_command));const availableExtensions=sortedUnique(candidates.map(entry=>entry.name));throw new Error(`Expected flags for target command "${expectedCommand}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available flag target commands: ${formatAvailable(available)}; matching extensions: ${formatAvailable(availableExtensions)}`)}if(expectation.flags!==void 0){const actualFlagLabels=collectFlagLabels(registration.flags);const missingFlags=expectation.flags.filter(flag=>!actualFlagLabels.has(flag));if(missingFlags.length>0){throw new Error(`Expected flags for target command "${expectedCommand}" to include ${formatAvailable(expectation.flags)}; missing ${formatAvailable(missingFlags)}; available ${formatAvailable([...actualFlagLabels].sort((left,right)=>left.localeCompare(right)))}`)}}return registration}function assertRegisteredHook(hooks,expectation){const field=HOOK_KIND_TO_REGISTRY_FIELD[expectation.kind];const candidates=hooks[field]??[];const hook=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!hook){const available=sortedUnique(candidates.map(entry=>entry.name));throw new Error(`Expected a "${expectation.kind}" hook${extensionNameSuffix(expectation.extensionName)} to be registered. Available "${expectation.kind}" hooks: ${formatAvailable(available)}`)}return hook}function assertRegisteredSearchProvider(registrations,expectation){const expectedProvider=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.provider));if(expectedProvider.length===0){throw new Error("Expected search provider name must be a non-empty string")}const candidates=registrations.search_providers.filter(entry=>normalizeSdkIdentifier(entry.definition.name)===expectedProvider);const provider=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!provider){const available=sortedUnique(registrations.search_providers.map(entry=>entry.definition.name));throw new Error(`Expected search provider "${expectedProvider}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available search providers: ${formatAvailable(available)}`)}return provider}function assertRegisteredVectorStoreAdapter(registrations,expectation){const expectedAdapter=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.adapter));if(expectedAdapter.length===0){throw new Error("Expected vector store adapter name must be a non-empty string")}const candidates=registrations.vector_store_adapters.filter(entry=>normalizeSdkIdentifier(entry.definition.name)===expectedAdapter);const adapter=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!adapter){const available=sortedUnique(registrations.vector_store_adapters.map(entry=>entry.definition.name));throw new Error(`Expected vector store adapter "${expectedAdapter}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available vector store adapters: ${formatAvailable(available)}`)}return adapter}function assertRegisteredImporter(registrations,expectation){const expectedImporter=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.importer));if(expectedImporter.length===0){throw new Error("Expected importer name must be a non-empty string")}const candidates=registrations.importers.filter(entry=>normalizeSdkIdentifier(entry.importer)===expectedImporter);const importer=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!importer){const available=sortedUnique(registrations.importers.map(entry=>entry.importer));throw new Error(`Expected importer "${expectedImporter}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available importers: ${formatAvailable(available)}`)}return importer}function assertRegisteredExporter(registrations,expectation){const expectedExporter=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.exporter));if(expectedExporter.length===0){throw new Error("Expected exporter name must be a non-empty string")}const candidates=registrations.exporters.filter(entry=>normalizeSdkIdentifier(entry.exporter)===expectedExporter);const exporter=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!exporter){const available=sortedUnique(registrations.exporters.map(entry=>entry.exporter));throw new Error(`Expected exporter "${expectedExporter}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available exporters: ${formatAvailable(available)}`)}return exporter}function assertRegisteredItemField(registrations,expectation){const expectedField=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.field));if(expectedField.length===0){throw new Error("Expected item field name must be a non-empty string")}const candidates=registrations.item_fields.filter(entry=>expectation.extensionName===void 0||entry.name===expectation.extensionName).map(registration=>({registration,field:registration.fields.find(field=>normalizeSdkIdentifier(field.name)===expectedField)})).filter(entry=>entry.field!==void 0);const match=candidates.find(entry=>expectation.type===void 0||entry.field.type===expectation.type);if(!match){const available=sortedUnique(registrations.item_fields.flatMap(entry=>entry.fields.map(field=>`${field.name}:${field.type}`)));throw new Error(`Expected item field "${expectedField}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available item fields: ${formatAvailable(available)}`)}return match}function assertRegisteredItemType(registrations,expectation){const expectedType=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.itemType));if(expectedType.length===0){throw new Error("Expected item type name must be a non-empty string")}const candidates=registrations.item_types.filter(entry=>expectation.extensionName===void 0||entry.name===expectation.extensionName).map(registration=>({registration,itemType:registration.types.find(itemType=>normalizeSdkIdentifier(itemType.name)===expectedType)})).filter(entry=>entry.itemType!==void 0);const match=candidates.find(entry=>expectation.folder===void 0||entry.itemType.folder===expectation.folder);if(!match){const available=sortedUnique(registrations.item_types.flatMap(entry=>entry.types.map(itemType=>`${itemType.name}:${itemType.folder}`)));throw new Error(`Expected item type "${expectedType}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available item types: ${formatAvailable(available)}`)}return match}function assertRegisteredProfile(registrations,expectation){const expectedProfile=normalizeSdkProfileMatchKey(registeredExpectationName(expectation,expectation.profile));if(expectedProfile.length===0){throw new Error("Expected profile name must be a non-empty string")}const match=registrations.profiles.filter(entry=>expectation.extensionName===void 0||entry.name===expectation.extensionName).find(entry=>normalizeSdkProfileMatchKey(entry.profile.name)===expectedProfile);if(!match){const available=sortedUnique(registrations.profiles.map(entry=>entry.profile.name));throw new Error(`Expected profile "${expectedProfile}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available profiles: ${formatAvailable(available)}`)}return{registration:match,profile:match.profile}}function assertRegisteredCommandOverride(commands,expectation){const expectedCommand=normalizeSdkCommandName(registeredExpectationName(expectation,expectation.command));if(expectedCommand.length===0){throw new Error("Expected command name must be a non-empty string")}const candidates=commands.overrides.filter(entry=>entry.command===expectedCommand);const override=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!override){const available=sortedUnique(commands.overrides.map(entry=>entry.command));throw new Error(`Expected command override "${expectedCommand}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available command overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredParserOverride(parsers,expectation){const expectedCommand=normalizeSdkCommandName(registeredExpectationName(expectation,expectation.command));if(expectedCommand.length===0){throw new Error("Expected command name must be a non-empty string")}const candidates=parsers.overrides.filter(entry=>entry.command===expectedCommand);const override=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!override){const available=sortedUnique(parsers.overrides.map(entry=>entry.command));throw new Error(`Expected parser override "${expectedCommand}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available parser overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredPreflightOverride(preflight,expectation={}){const override=expectation.extensionName?preflight.overrides.find(entry=>entry.name===expectation.extensionName):preflight.overrides[0];if(!override){const available=sortedUnique(preflight.overrides.map(entry=>entry.name));throw new Error(`Expected a preflight override${extensionNameSuffix(expectation.extensionName)} to be registered. Available preflight overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredRendererOverride(renderers,expectation){const expectedFormat=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.format));if(expectedFormat.length===0){throw new Error("Expected renderer format must be a non-empty string")}const candidates=renderers.overrides.filter(entry=>entry.format===expectedFormat);const override=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!override){const available=sortedUnique(renderers.overrides.map(entry=>entry.format));throw new Error(`Expected renderer override "${expectedFormat}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available renderer overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredServiceOverride(services,expectation){const expectedService=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.service));if(expectedService.length===0){throw new Error("Expected service name must be a non-empty string")}const candidates=services.overrides.filter(entry=>normalizeSdkIdentifier(entry.service)===expectedService);const override=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!override){const available=sortedUnique(services.overrides.map(entry=>entry.service));throw new Error(`Expected service override "${expectedService}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available service overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredMigration(registrations,expectation){const expectedMigration=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.migration));if(expectedMigration.length===0){throw new Error("Expected migration id must be a non-empty string")}const candidates=registrations.migrations.filter(entry=>(expectation.extensionName===void 0||entry.name===expectation.extensionName)&&typeof entry.definition.id==="string"&&normalizeSdkIdentifier(entry.definition.id)===expectedMigration);const match=candidates.find(entry=>expectation.mandatory===void 0||(entry.definition.mandatory??false)===expectation.mandatory);if(match){return match}const idMatch=candidates[0];if(idMatch!==void 0){throw new Error(`Expected migration "${expectedMigration}"${extensionNameSuffix(expectation.extensionName)} to have mandatory=${expectation.mandatory}, but it is mandatory=${idMatch.definition.mandatory??false}.`)}const available=sortedUnique(registrations.migrations.map(entry=>{const id=typeof entry.definition.id==="string"&&entry.definition.id.trim().length>0?entry.definition.id.trim():"(unnamed)";return`${id}:${entry.definition.mandatory===true}`}));throw new Error(`Expected migration "${expectedMigration}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available migrations: ${formatAvailable(available)}`)}function assertExtensionCapabilityUsage(activation,expectation){const toKnownCapabilitySet=(capabilities,field)=>{const known=new Set;for(const capability of capabilities){const normalized=normalizeKnownExtensionCapability(capability);if(normalized===null){throw new Error(`Expected ${field} capability "${capability}" to be a known extension capability. Use canonical capability names (see manifest.capabilities).`)}known.add(normalized)}return known};const declared=[...toKnownCapabilitySet(expectation.declared,"declared")].sort((left,right)=>left.localeCompare(right));const allowUnused=toKnownCapabilitySet(expectation.allowUnused??[],"allowUnused");const used=collectUsedExtensionCapabilities(activation,{extensionName:expectation.extensionName});const usedSet=new Set(used);const unused=declared.filter(capability=>!usedSet.has(capability)&&!allowUnused.has(capability));if(unused.length>0){const scopeSuffix=extensionNameSuffix(expectation.extensionName);throw new Error(`Expected every declared capability${scopeSuffix} to be exercised, but [${unused.join(", ")}] ${unused.length===1?"is":"are"} declared yet never registered against. Remove ${unused.length===1?"it":"them"} from manifest.capabilities for least privilege, or pass allowUnused for capabilities registered only behind a runtime flag.`)}return{declared,used,unused}}function assertExtensionBlueprint(blueprint,options={}){const result=lintExtensionBlueprint(blueprint,options);if(!result.ok){const errors=result.findings.filter(finding=>finding.severity==="error");throw new Error(`Extension blueprint failed preflight with ${errors.length} ${errors.length===1?"error":"errors"}:
2
- `+errors.map(finding=>` - [${finding.code}] ${finding.message}`).join("\n"))}return result}function assertProjectProfile(profile,options={}){const report=lintProjectProfile(profile);const blocking=report.findings.filter(finding=>finding.severity==="error"||options.strict===true&&finding.severity==="warning");if(blocking.length>0){throw new Error(`Project profile "${report.profile}" failed lint with ${blocking.length} ${blocking.length===1?"issue":"issues"}:
3
- `+blocking.map(finding=>` - ${finding.severity} [${finding.code}] ${finding.message}`).join("\n"))}return report}function assertExtensionManifestMatchesBlueprint(manifest,blueprint){const declaredCapabilities=Array.isArray(manifest.capabilities)?manifest.capabilities:[];const result=lintExtensionBlueprint(blueprint,{declaredCapabilities});const declared=result.declared;const declaredSet=new Set(declared);const usedSet=new Set(result.used);const missing=result.used.filter(capability=>!declaredSet.has(capability));const unused=declared.filter(capability=>!usedSet.has(capability));if(missing.length>0||unused.length>0){const parts=[];if(missing.length>0){parts.push(`missing [${missing.join(", ")}] (the blueprint registers ${missing.length===1?"a surface":"surfaces"} requiring ${missing.length===1?"it":"them"}; activation throws extension_capability_missing)`)}if(unused.length>0){parts.push(`unused [${unused.join(", ")}] (declared but no surface exercises ${unused.length===1?"it":"them"}; drop for least privilege)`)}throw new Error(`Manifest capabilities do not match the blueprint: ${parts.join("; ")}. Set capabilities to synthesizeExtensionManifest(blueprint, identity).capabilities to stay in sync.`)}return{used:result.used,declared,missing,unused,findings:result.findings}}function assertExtensionManifestCompatible(manifest,target){const result=checkExtensionManifestCompatibility(manifest,target);const blocking=result.findings.filter(finding=>finding.severity==="error");if(blocking.length>0){throw new Error(`Extension manifest is not compatible with pm ${result.pmVersion}: ${blocking.map(finding=>finding.message).join("; ")}`)}return result}function assertExtensionPreflight(blueprint,options={}){const report=preflightExtension(blueprint,options);if(!report.ok){const errors=report.findings.filter(finding=>finding.severity==="error");throw new Error(`Extension failed preflight with ${errors.length} ${errors.length===1?"error":"errors"}:
4
- `+errors.map(finding=>` - [${finding.source}:${finding.code}] ${finding.message}`).join("\n"))}return report}function assertTestModuleHasActivateExport(module){if(resolveActivatablePropertyRecord(module)){return}throw new Error("createExtensionTestHarness received a module with no activate export. Pass the extension module (with an activate(api) function on the module or its default export) as the first argument, and options second.")}async function createExtensionTestHarness(module,options={}){assertTestModuleHasActivateExport(module);const manifest=readTestExtensionManifest(module);const name=resolveTestExtensionName(manifest,options.name);const layer=options.layer??"project";const activation=await activateExtensionForTest(module,options);if(activation.failed.length>0){const detail=activation.failed.map(failure=>{const missingCapability=failure.trace?.missing_capability;const reason=missingCapability?`${failure.error}; missing capability "${missingCapability}"`:failure.error;return`${failure.layer}:${failure.name} (${reason})`}).join(", ");throw new Error(`createExtensionTestHarness could not activate the extension cleanly: ${detail}. Declare the required capability in the manifest (or pass it via options.capabilities), or use activateExtensionForTest directly to inspect a failed activation.`)}return{module,name,layer,activation,activationSummary(describeOptions){return describeExtensionActivation(activation,describeOptions)},renderMarkdown(markdownOptions={}){const{extensionName,...renderOptions}=markdownOptions??{};return renderExtensionSurfaceMarkdown(describeExtensionActivation(activation,{extensionName}),renderOptions)},assertCommandContract(expectation){return assertRegisteredCommandContract(activation.registrations,expectation)},assertFlags(expectation){return assertRegisteredFlags(activation.registrations,expectation)},assertItemField(expectation){return assertRegisteredItemField(activation.registrations,expectation)},assertItemType(expectation){return assertRegisteredItemType(activation.registrations,expectation)},assertProfile(expectation){return assertRegisteredProfile(activation.registrations,expectation)},assertHook(expectation){return assertRegisteredHook(activation.hooks,expectation)},assertCommandOverride(expectation){return assertRegisteredCommandOverride(activation.commands,expectation)},assertParserOverride(expectation){return assertRegisteredParserOverride(activation.parsers,expectation)},assertPreflightOverride(expectation){return assertRegisteredPreflightOverride(activation.preflight,expectation)},assertRendererOverride(expectation){return assertRegisteredRendererOverride(activation.renderers,expectation)},assertServiceOverride(expectation){return assertRegisteredServiceOverride(activation.services,expectation)},assertSearchProvider(expectation){return assertRegisteredSearchProvider(activation.registrations,expectation)},assertVectorStoreAdapter(expectation){return assertRegisteredVectorStoreAdapter(activation.registrations,expectation)},assertImporter(expectation){return assertRegisteredImporter(activation.registrations,expectation)},assertExporter(expectation){return assertRegisteredExporter(activation.registrations,expectation)},assertMigration(expectation){return assertRegisteredMigration(activation.registrations,expectation)},assertCapabilityUsage(expectation){return assertExtensionCapabilityUsage(activation,expectation)},runCommand(runOptions){return runRegisteredCommandForTest(activation.commands,runOptions)},runHook(runOptions){return runRegisteredHookForTest(activation.hooks,runOptions)},runMutationGuard(runOptions){return runRegisteredMutationGuardForTest(activation.hooks,runOptions)},runCommandOverride(context){return runRegisteredCommandOverrideForTest(activation.commands,context)},runParserOverride(context){return runRegisteredParserOverrideForTest(activation.parsers,context)},runPreflightOverride(context){return runRegisteredPreflightOverrideForTest(activation.preflight,context)},runRendererOverride(context){return runRegisteredRendererOverrideForTest(activation.renderers,context)},runServiceOverride(context){return runRegisteredServiceOverrideForTest(activation.services,context)},runSearchProvider(runOptions){return runRegisteredSearchProviderForTest(activation.registrations,runOptions)},runVectorStoreAdapter(runOptions){return runRegisteredVectorStoreAdapterForTest(activation.registrations,runOptions)},runMigration(runOptions){return runRegisteredMigrationForTest(activation.registrations,runOptions)},runImporter(runOptions){return runRegisteredImporterForTest(activation,runOptions)},runExporter(runOptions){return runRegisteredExporterForTest(activation,runOptions)},deactivate(deactivateOptions={}){return deactivateExtensionForTest(module,{name,layer,activation,deactivateTimeoutMs:deactivateOptions.deactivateTimeoutMs})}}}export{activateExtensionForTest,assertExtensionBlueprint,assertExtensionCapabilityUsage,assertExtensionDeactivated,assertExtensionManifestCompatible,assertExtensionManifestMatchesBlueprint,assertExtensionPreflight,assertPackageManifest,assertProjectProfile,assertRegisteredCommandContract,assertRegisteredCommandOverride,assertRegisteredExporter,assertRegisteredFlags,assertRegisteredHook,assertRegisteredImporter,assertRegisteredItemField,assertRegisteredItemType,assertRegisteredMigration,assertRegisteredParserOverride,assertRegisteredPreflightOverride,assertRegisteredProfile,assertRegisteredRendererOverride,assertRegisteredSearchProvider,assertRegisteredServiceOverride,assertRegisteredVectorStoreAdapter,createExtensionTestHarness,deactivateExtensionForTest,describeExtensionActivation,describeExtensionBlueprint,lintExtensionBlueprint,renderExtensionSurfaceMarkdown,runRegisteredCommandForTest,runRegisteredCommandOverrideForTest,runRegisteredExporterForTest,runRegisteredHookForTest,runRegisteredImporterForTest,runRegisteredMigrationForTest,runRegisteredMutationGuardForTest,runRegisteredParserOverrideForTest,runRegisteredPreflightOverrideForTest,runRegisteredRendererOverrideForTest,runRegisteredSearchProviderForTest,runRegisteredServiceOverrideForTest,runRegisteredVectorStoreAdapterForTest};
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]="2df3e178-3a2b-5a45-89d8-628eca782453")}catch{}})();import{activateExtensions,deactivateExtensions,runAfterCommandHooks,runBeforeCommandHooks,runBeforeMutationHooks,runCommandHandler,runCommandOverride,runOnIndexHooks,runOnReadHooks,runOnWriteHooks,runParserOverride,runPreflightOverride,runRendererOverride,runServiceOverride}from"../core/extensions/loader.js";import{createDefaultExtensionGovernancePolicy}from"../core/extensions/extension-types.js";import{getMigrationRuntimeDefinition,resolveRegisteredSearchProvider,resolveRegisteredVectorStoreAdapter}from"../core/extensions/runtime-registrations.js";import{collectUsedExtensionCapabilities}from"../core/extensions/capability-usage.js";import{normalizeKnownExtensionCapability}from"../core/extensions/extension-capability-aliases.js";import{checkExtensionManifestCompatibility,describeExtensionBlueprint,lintExtensionBlueprint,preflightExtension}from"./compose.js";import{describeExtensionActivation}from"../core/extensions/activation-summary.js";import{lintProjectProfile}from"../core/profile/profile-lint.js";import{renderExtensionSurfaceMarkdown}from"../core/extensions/activation-summary-markdown.js";import{asPropertyRecord,resolveActivatablePropertyRecord}from"../core/shared/primitives.js";import{createExtensionCommandSdk}from"./extension-command-context.js";import{PmClient}from"./runtime.js";function registeredExpectationName(expectation,legacyValue){return expectation.name??legacyValue??""}const HOOK_KIND_TO_REGISTRY_FIELD={before_command:"beforeCommand",before_mutation:"beforeMutation",after_command:"afterCommand",on_read:"onRead",on_write:"onWrite",on_index:"onIndex"},RUNNABLE_HOOK_KIND_TO_REGISTRY_FIELD={before_command:"beforeCommand",after_command:"afterCommand",on_read:"onRead",on_write:"onWrite",on_index:"onIndex"};function normalizeSdkIdentifier(value){return value.trim().toLowerCase()}function normalizeSdkProfileMatchKey(value){return normalizeSdkIdentifier(value).replaceAll("-","_")}function extensionNameSuffix(extensionName){return extensionName?` from extension "${extensionName}"`:""}function sortedUnique(values){return[...new Set(values)].sort((left,right)=>left.localeCompare(right))}function normalizeSdkCommandName(command){if(typeof command!="string")throw new Error('A command name string is required. Pass it via the options object, e.g. runRegisteredCommandForTest(activation, { command: "my command" }) \u2014 positional command arguments are not supported.');return command.trim().toLowerCase().split(/\s+/).filter(part=>part.length>0).join(" ")}function formatAvailable(values){return values.length>0?values.join(", "):"(none)"}function assertStringSetIncludes(actual,expected,label){const actualValues=new Set(actual??[]),missing=sortedUnique(expected.filter(value=>!actualValues.has(value)));if(missing.length>0)throw new Error(`Expected package manifest ${label} to include ${missing.join(", ")}; available: ${formatAvailable(sortedUnique(actual??[]))}`)}function collectFlagLabels(flags){const labels=new Set;for(const flag of flags)typeof flag.long=="string"&&flag.long.trim().length>0&&labels.add(flag.long.trim()),typeof flag.short=="string"&&flag.short.trim().length>0&&labels.add(flag.short.trim());return labels}function readTestExtensionManifest(module){const moduleRecord=asPropertyRecord(module);if(!moduleRecord)return{};const manifest=asPropertyRecord(moduleRecord.manifest);if(manifest)return manifest;const defaultExport=asPropertyRecord(moduleRecord.default);return asPropertyRecord(defaultExport?.manifest)||(defaultExport&&typeof moduleRecord.default!="function"&&("name"in defaultExport||"capabilities"in defaultExport)?defaultExport:typeof module!="function"&&("name"in moduleRecord||"capabilities"in moduleRecord)?moduleRecord:{})}function resolveTestExtensionName(manifest,explicitName){return explicitName??(typeof manifest.name=="string"&&manifest.name.trim().length>0?manifest.name.trim():"test-extension")}function readTestExtensionCapabilities(manifest,options){return Array.isArray(options.capabilities)?[...options.capabilities]:Array.isArray(manifest.capabilities)?manifest.capabilities.filter(capability=>typeof capability=="string"):[]}function buildSingleExtensionLoadResult(module,manifest,identity){return{disabled_by_flag:!1,roots:{global:"",project:""},configured_enabled:[],configured_disabled:[],discovered:[],effective:[],warnings:[],policy:identity.policy,failed:[],loaded:[{layer:identity.layer,directory:"",manifest_path:"",name:identity.name,version:typeof manifest.version=="string"?manifest.version:"0.0.0",entry:typeof manifest.entry=="string"?manifest.entry:"./index.js",priority:typeof manifest.priority=="number"?manifest.priority:0,entry_path:"",capabilities:identity.capabilities,manifest_version:typeof manifest.manifest_version=="number"?manifest.manifest_version:void 0,pm_min_version:typeof manifest.pm_min_version=="string"?manifest.pm_min_version:void 0,pm_max_version:typeof manifest.pm_max_version=="string"?manifest.pm_max_version:void 0,engines:manifest.engines,trusted:manifest.trusted,provenance:manifest.provenance,sandbox_profile:manifest.sandbox_profile,permissions:manifest.permissions,activation:manifest.activation,module}]}}async function activateExtensionForTest(module,options={}){const manifest=readTestExtensionManifest(module);return activateExtensions(buildSingleExtensionLoadResult(module,manifest,{name:resolveTestExtensionName(manifest,options.name),layer:options.layer??"project",capabilities:readTestExtensionCapabilities(manifest,options),policy:options.policy??createDefaultExtensionGovernancePolicy()}))}async function deactivateExtensionForTest(module,options={}){const manifest=readTestExtensionManifest(module);return deactivateExtensions(buildSingleExtensionLoadResult(module,manifest,{name:resolveTestExtensionName(manifest,options.name),layer:options.layer??"project",capabilities:readTestExtensionCapabilities(manifest,{}),policy:createDefaultExtensionGovernancePolicy()}),options.activation,options.deactivateTimeoutMs===void 0?{}:{deactivate_timeout_ms:options.deactivateTimeoutMs})}async function runRegisteredCommandForTest(commands,options){const command=normalizeSdkCommandName(options.command);if(command.length===0)throw new Error("Expected command name must be a non-empty string");if(!commands.handlers.some(entry=>entry.command===command)){const available=sortedUnique(commands.handlers.map(entry=>entry.command));throw new Error(`Expected a registered command handler for "${command}" to invoke. Available command handlers: ${formatAvailable(available)}`)}if(options.sdk!==void 0&&options.sdkFactory!==void 0)throw new TypeError("runRegisteredCommandForTest accepts sdk or sdkFactory, not both");const pmRoot=options.pmRoot??"",global2={json:!0,quiet:!0,noPager:!0,...options.global},sdk=options.sdk??options.sdkFactory?.({pmRoot,global:global2})??(pmRoot.length>0?createExtensionCommandSdk(pmRoot,new PmClient({pmRoot}),void 0,command):void 0);return runCommandHandler(commands,{command,args:options.args?[...options.args]:[],options:options.options?{...options.options}:{},global:global2,pm_root:pmRoot,...sdk===void 0?{}:{sdk}})}async function runRegisteredMutationGuardForTest(hooks,options){if((hooks.beforeMutation?.length??0)===0)throw new Error("Expected a registered before_mutation hook to invoke");await runBeforeMutationHooks(hooks,options.context)}async function runRegisteredHookForTest(hooks,options){const kind=options.kind;if(kind==="before_mutation")throw new Error("Invoke before_mutation hooks with runRegisteredMutationGuardForTest so denials and failures retain fail-closed semantics.");if((hooks[RUNNABLE_HOOK_KIND_TO_REGISTRY_FIELD[kind]]?.length??0)===0){const populatedKinds=sortedUnique(Object.keys(RUNNABLE_HOOK_KIND_TO_REGISTRY_FIELD).filter(candidateKind=>(hooks[RUNNABLE_HOOK_KIND_TO_REGISTRY_FIELD[candidateKind]]?.length??0)>0));throw new Error(`Expected a registered "${kind}" hook to invoke. Hook kinds with registrations: ${formatAvailable(populatedKinds)}`)}switch(options.kind){case"before_command":return runBeforeCommandHooks(hooks,options.context);case"after_command":return runAfterCommandHooks(hooks,options.context);case"on_read":return runOnReadHooks(hooks,options.context);case"on_write":return runOnWriteHooks(hooks,options.context);case"on_index":return runOnIndexHooks(hooks,options.context)}}async function runRegisteredParserOverrideForTest(parsers,context){const command=normalizeSdkCommandName(context.command);if(!parsers.overrides.some(entry=>entry.command===command))throw new Error(`Expected a registered parser override for command "${command}" to invoke. Available parser override commands: ${formatAvailable(sortedUnique(parsers.overrides.map(entry=>entry.command)))}`);return runParserOverride(parsers,context)}async function runRegisteredPreflightOverrideForTest(preflight,context){if(preflight.overrides.length===0)throw new Error("Expected a registered preflight override to invoke, but none are registered.");return runPreflightOverride(preflight,context)}async function runRegisteredCommandOverrideForTest(commands,context){const command=normalizeSdkCommandName(context.command);if(!commands.overrides.some(entry=>entry.command===command))throw new Error(`Expected a registered command override for command "${command}" to invoke. Available command override commands: ${formatAvailable(sortedUnique(commands.overrides.map(entry=>entry.command)))}`);return runCommandOverride(commands,context)}async function runRegisteredRendererOverrideForTest(renderers,context){if(!renderers.overrides.some(entry=>entry.format===context.format))throw new Error(`Expected a registered renderer override for format "${context.format}" to invoke. Available renderer override formats: ${formatAvailable(sortedUnique(renderers.overrides.map(entry=>entry.format)))}`);return runRendererOverride(renderers,context)}async function runRegisteredServiceOverrideForTest(services,context){if(!services.overrides.some(entry=>entry.service===context.service))throw new Error(`Expected a registered service override for service "${context.service}" to invoke. Available service override services: ${formatAvailable(sortedUnique(services.overrides.map(entry=>entry.service)))}`);return runServiceOverride(services,context)}const SEARCH_PROVIDER_OPERATION_DEFINITION_KEYS={query:["query"],embed:["embed"],embedBatch:["embedBatch","embed_batch"],queryExpansion:["queryExpansion","query_expansion"],rerank:["rerank"]};async function runRegisteredSearchProviderForTest(registrations,options){const registration=resolveRegisteredSearchProvider(registrations,options.provider);if(!registration){const available=sortedUnique(registrations.search_providers.map(entry=>entry.definition.name));throw new Error(`Expected a registered search provider "${options.provider}" to invoke. Available search providers: ${formatAvailable(available)}`)}const runtimeDefinition=registration.runtime_definition,operationFn=SEARCH_PROVIDER_OPERATION_DEFINITION_KEYS[options.operation].map(key=>runtimeDefinition[key]).find(value=>typeof value=="function");if(typeof operationFn!="function")throw new Error(`Registered search provider "${options.provider}" does not implement the "${options.operation}" operation.`);return await operationFn(options.context)}async function runRegisteredVectorStoreAdapterForTest(registrations,options){const registration=resolveRegisteredVectorStoreAdapter(registrations,options.adapter);if(!registration){const available=sortedUnique(registrations.vector_store_adapters.map(entry=>entry.definition.name));throw new Error(`Expected a registered vector store adapter "${options.adapter}" to invoke. Available vector store adapters: ${formatAvailable(available)}`)}const operationFn=registration.runtime_definition[options.operation];if(typeof operationFn!="function")throw new Error(`Registered vector store adapter "${options.adapter}" does not implement the "${options.operation}" operation.`);return await operationFn(options.context)}async function runRegisteredMigrationForTest(registrations,options){const migration=assertRegisteredMigration(registrations,{migration:options.migration,extensionName:options.extensionName}),run=getMigrationRuntimeDefinition(migration).run;if(typeof run!="function")throw new Error(`Registered migration "${options.migration}" does not implement a run function to invoke.`);const declaredStatus=migration.definition.status,context={id:migration.definition.id,command:"migration",layer:migration.layer,extension:migration.name,pm_root:options.pmRoot??"",status:(typeof declaredStatus=="string"?declaredStatus.trim().toLowerCase():"")||"pending"};return await run(context)}async function runRegisteredImporterForTest(activation,options){const importer=assertRegisteredImporter(activation.registrations,{importer:options.importer,extensionName:options.extensionName});return runRegisteredCommandForTest(activation.commands,{command:`${importer.importer} import`,args:options.args,options:options.options,global:options.global,pmRoot:options.pmRoot})}async function runRegisteredExporterForTest(activation,options){const exporter=assertRegisteredExporter(activation.registrations,{exporter:options.exporter,extensionName:options.extensionName});return runRegisteredCommandForTest(activation.commands,{command:`${exporter.exporter} export`,args:options.args,options:options.options,global:options.global,pmRoot:options.pmRoot})}function assertExtensionDeactivated(result,expectation={}){const expectedDeactivated=expectation.deactivated??1;if(result.deactivated!==expectedDeactivated)throw new Error(`Expected ${expectedDeactivated} extension${expectedDeactivated===1?"":"s"} to deactivate cleanly, but ${result.deactivated} did.`);const expectedFailed=expectation.failed??0;if(result.failed.length!==expectedFailed){const detail=result.failed.map(failure=>`${failure.layer}:${failure.name} (${failure.error})`).join(", ");throw new Error(`Expected ${expectedFailed} teardown failure${expectedFailed===1?"":"s"}, but observed ${result.failed.length}${detail.length>0?`: ${detail}`:""}.`)}return result}function assertPackageManifest(manifest,expectation){if(expectation.packageName!==void 0&&manifest.package_name!==expectation.packageName)throw new Error(`Expected package manifest package_name to be "${expectation.packageName}"; received "${manifest.package_name??"(none)"}"`);if(expectation.aliases!==void 0&&assertStringSetIncludes(manifest.aliases,expectation.aliases,"aliases"),expectation.resources!==void 0)for(const[kind,expectedPaths]of Object.entries(expectation.resources))assertStringSetIncludes(manifest.resources[kind],expectedPaths,`pm.${kind}`);return manifest}function assertRegisteredCommandContract(registrations,expectation){const expectedCommand=normalizeSdkCommandName(registeredExpectationName(expectation,expectation.command));if(expectedCommand.length===0)throw new Error("Expected command name must be a non-empty string");const commandCandidates=registrations.commands.filter(entry=>entry.command===expectedCommand),command=expectation.extensionName?commandCandidates.find(entry=>entry.name===expectation.extensionName):commandCandidates[0];if(!command){const available=registrations.commands.map(entry=>entry.command).sort((left,right)=>left.localeCompare(right)),extensionSuffix=expectation.extensionName?` from extension "${expectation.extensionName}"`:"";throw new Error(`Expected extension command "${expectedCommand}"${extensionSuffix} to be registered. Available commands: ${formatAvailable(available)}`)}if(expectation.action!==void 0&&command.action!==expectation.action)throw new Error(`Expected extension command "${expectedCommand}" action "${expectation.action}", received "${command.action}"`);if(expectation.arguments!==void 0){const actualArguments=(command.arguments??[]).map(argument=>argument.name),missingArguments=expectation.arguments.filter(argument=>!actualArguments.includes(argument));if(missingArguments.length>0)throw new Error(`Expected extension command "${expectedCommand}" arguments ${formatAvailable(expectation.arguments)}; missing ${formatAvailable(missingArguments)}; available ${formatAvailable(actualArguments)}`)}const flags=registrations.flags.filter(entry=>entry.target_command===expectedCommand&&(expectation.extensionName===void 0||entry.name===expectation.extensionName)).flatMap(entry=>entry.flags);if(expectation.flags!==void 0){const actualFlagLabels=collectFlagLabels(flags),missingFlags=expectation.flags.filter(flag=>!actualFlagLabels.has(flag));if(missingFlags.length>0)throw new Error(`Expected extension command "${expectedCommand}" flags ${formatAvailable(expectation.flags)}; missing ${formatAvailable(missingFlags)}; available ${formatAvailable([...actualFlagLabels].sort((left,right)=>left.localeCompare(right)))}`)}return{command,flags}}function assertRegisteredFlags(registrations,expectation){const expectedCommand=normalizeSdkCommandName(registeredExpectationName(expectation,expectation.targetCommand));if(expectedCommand.length===0)throw new Error("Expected target command name must be a non-empty string");const candidates=registrations.flags.filter(entry=>entry.target_command===expectedCommand);let registration;if(expectation.extensionName)registration=candidates.find(entry=>entry.name===expectation.extensionName);else if(candidates.length===1)registration=candidates[0];else if(candidates.length>1){const availableExtensions=sortedUnique(candidates.map(entry=>entry.name));throw new Error(`Expected flags for target command "${expectedCommand}" matched multiple extensions: ${formatAvailable(availableExtensions)}. Specify extensionName to choose one registration.`)}if(!registration){const available=sortedUnique(registrations.flags.map(entry=>entry.target_command)),availableExtensions=sortedUnique(candidates.map(entry=>entry.name));throw new Error(`Expected flags for target command "${expectedCommand}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available flag target commands: ${formatAvailable(available)}; matching extensions: ${formatAvailable(availableExtensions)}`)}if(expectation.flags!==void 0){const actualFlagLabels=collectFlagLabels(registration.flags),missingFlags=expectation.flags.filter(flag=>!actualFlagLabels.has(flag));if(missingFlags.length>0)throw new Error(`Expected flags for target command "${expectedCommand}" to include ${formatAvailable(expectation.flags)}; missing ${formatAvailable(missingFlags)}; available ${formatAvailable([...actualFlagLabels].sort((left,right)=>left.localeCompare(right)))}`)}return registration}function assertRegisteredHook(hooks,expectation){const field=HOOK_KIND_TO_REGISTRY_FIELD[expectation.kind],candidates=hooks[field]??[],hook=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!hook){const available=sortedUnique(candidates.map(entry=>entry.name));throw new Error(`Expected a "${expectation.kind}" hook${extensionNameSuffix(expectation.extensionName)} to be registered. Available "${expectation.kind}" hooks: ${formatAvailable(available)}`)}return hook}function assertRegisteredSearchProvider(registrations,expectation){const expectedProvider=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.provider));if(expectedProvider.length===0)throw new Error("Expected search provider name must be a non-empty string");const candidates=registrations.search_providers.filter(entry=>normalizeSdkIdentifier(entry.definition.name)===expectedProvider),provider=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!provider){const available=sortedUnique(registrations.search_providers.map(entry=>entry.definition.name));throw new Error(`Expected search provider "${expectedProvider}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available search providers: ${formatAvailable(available)}`)}return provider}function assertRegisteredVectorStoreAdapter(registrations,expectation){const expectedAdapter=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.adapter));if(expectedAdapter.length===0)throw new Error("Expected vector store adapter name must be a non-empty string");const candidates=registrations.vector_store_adapters.filter(entry=>normalizeSdkIdentifier(entry.definition.name)===expectedAdapter),adapter=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!adapter){const available=sortedUnique(registrations.vector_store_adapters.map(entry=>entry.definition.name));throw new Error(`Expected vector store adapter "${expectedAdapter}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available vector store adapters: ${formatAvailable(available)}`)}return adapter}function assertRegisteredImporter(registrations,expectation){const expectedImporter=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.importer));if(expectedImporter.length===0)throw new Error("Expected importer name must be a non-empty string");const candidates=registrations.importers.filter(entry=>normalizeSdkIdentifier(entry.importer)===expectedImporter),importer=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!importer){const available=sortedUnique(registrations.importers.map(entry=>entry.importer));throw new Error(`Expected importer "${expectedImporter}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available importers: ${formatAvailable(available)}`)}return importer}function assertRegisteredExporter(registrations,expectation){const expectedExporter=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.exporter));if(expectedExporter.length===0)throw new Error("Expected exporter name must be a non-empty string");const candidates=registrations.exporters.filter(entry=>normalizeSdkIdentifier(entry.exporter)===expectedExporter),exporter=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!exporter){const available=sortedUnique(registrations.exporters.map(entry=>entry.exporter));throw new Error(`Expected exporter "${expectedExporter}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available exporters: ${formatAvailable(available)}`)}return exporter}function assertRegisteredItemField(registrations,expectation){const expectedField=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.field));if(expectedField.length===0)throw new Error("Expected item field name must be a non-empty string");const match=registrations.item_fields.filter(entry=>expectation.extensionName===void 0||entry.name===expectation.extensionName).map(registration=>({registration,field:registration.fields.find(field=>normalizeSdkIdentifier(field.name)===expectedField)})).filter(entry=>entry.field!==void 0).find(entry=>expectation.type===void 0||entry.field.type===expectation.type);if(!match){const available=sortedUnique(registrations.item_fields.flatMap(entry=>entry.fields.map(field=>`${field.name}:${field.type}`)));throw new Error(`Expected item field "${expectedField}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available item fields: ${formatAvailable(available)}`)}return match}function assertRegisteredItemType(registrations,expectation){const expectedType=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.itemType));if(expectedType.length===0)throw new Error("Expected item type name must be a non-empty string");const match=registrations.item_types.filter(entry=>expectation.extensionName===void 0||entry.name===expectation.extensionName).map(registration=>({registration,itemType:registration.types.find(itemType=>normalizeSdkIdentifier(itemType.name)===expectedType)})).filter(entry=>entry.itemType!==void 0).find(entry=>expectation.folder===void 0||entry.itemType.folder===expectation.folder);if(!match){const available=sortedUnique(registrations.item_types.flatMap(entry=>entry.types.map(itemType=>`${itemType.name}:${itemType.folder}`)));throw new Error(`Expected item type "${expectedType}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available item types: ${formatAvailable(available)}`)}return match}function assertRegisteredProfile(registrations,expectation){const expectedProfile=normalizeSdkProfileMatchKey(registeredExpectationName(expectation,expectation.profile));if(expectedProfile.length===0)throw new Error("Expected profile name must be a non-empty string");const match=registrations.profiles.filter(entry=>expectation.extensionName===void 0||entry.name===expectation.extensionName).find(entry=>normalizeSdkProfileMatchKey(entry.profile.name)===expectedProfile);if(!match){const available=sortedUnique(registrations.profiles.map(entry=>entry.profile.name));throw new Error(`Expected profile "${expectedProfile}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available profiles: ${formatAvailable(available)}`)}return{registration:match,profile:match.profile}}function assertRegisteredCommandOverride(commands,expectation){const expectedCommand=normalizeSdkCommandName(registeredExpectationName(expectation,expectation.command));if(expectedCommand.length===0)throw new Error("Expected command name must be a non-empty string");const candidates=commands.overrides.filter(entry=>entry.command===expectedCommand),override=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!override){const available=sortedUnique(commands.overrides.map(entry=>entry.command));throw new Error(`Expected command override "${expectedCommand}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available command overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredParserOverride(parsers,expectation){const expectedCommand=normalizeSdkCommandName(registeredExpectationName(expectation,expectation.command));if(expectedCommand.length===0)throw new Error("Expected command name must be a non-empty string");const candidates=parsers.overrides.filter(entry=>entry.command===expectedCommand),override=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!override){const available=sortedUnique(parsers.overrides.map(entry=>entry.command));throw new Error(`Expected parser override "${expectedCommand}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available parser overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredPreflightOverride(preflight,expectation={}){const override=expectation.extensionName?preflight.overrides.find(entry=>entry.name===expectation.extensionName):preflight.overrides[0];if(!override){const available=sortedUnique(preflight.overrides.map(entry=>entry.name));throw new Error(`Expected a preflight override${extensionNameSuffix(expectation.extensionName)} to be registered. Available preflight overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredRendererOverride(renderers,expectation){const expectedFormat=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.format));if(expectedFormat.length===0)throw new Error("Expected renderer format must be a non-empty string");const candidates=renderers.overrides.filter(entry=>entry.format===expectedFormat),override=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!override){const available=sortedUnique(renderers.overrides.map(entry=>entry.format));throw new Error(`Expected renderer override "${expectedFormat}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available renderer overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredServiceOverride(services,expectation){const expectedService=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.service));if(expectedService.length===0)throw new Error("Expected service name must be a non-empty string");const candidates=services.overrides.filter(entry=>normalizeSdkIdentifier(entry.service)===expectedService),override=expectation.extensionName?candidates.find(entry=>entry.name===expectation.extensionName):candidates[0];if(!override){const available=sortedUnique(services.overrides.map(entry=>entry.service));throw new Error(`Expected service override "${expectedService}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available service overrides: ${formatAvailable(available)}`)}return override}function assertRegisteredMigration(registrations,expectation){const expectedMigration=normalizeSdkIdentifier(registeredExpectationName(expectation,expectation.migration));if(expectedMigration.length===0)throw new Error("Expected migration id must be a non-empty string");const candidates=registrations.migrations.filter(entry=>(expectation.extensionName===void 0||entry.name===expectation.extensionName)&&typeof entry.definition.id=="string"&&normalizeSdkIdentifier(entry.definition.id)===expectedMigration),match=candidates.find(entry=>expectation.mandatory===void 0||(entry.definition.mandatory??!1)===expectation.mandatory);if(match)return match;const idMatch=candidates[0];if(idMatch!==void 0)throw new Error(`Expected migration "${expectedMigration}"${extensionNameSuffix(expectation.extensionName)} to have mandatory=${expectation.mandatory}, but it is mandatory=${idMatch.definition.mandatory??!1}.`);const available=sortedUnique(registrations.migrations.map(entry=>`${typeof entry.definition.id=="string"&&entry.definition.id.trim().length>0?entry.definition.id.trim():"(unnamed)"}:${entry.definition.mandatory===!0}`));throw new Error(`Expected migration "${expectedMigration}"${extensionNameSuffix(expectation.extensionName)} to be registered. Available migrations: ${formatAvailable(available)}`)}function assertExtensionCapabilityUsage(activation,expectation){const toKnownCapabilitySet=(capabilities,field)=>{const known=new Set;for(const capability of capabilities){const normalized=normalizeKnownExtensionCapability(capability);if(normalized===null)throw new Error(`Expected ${field} capability "${capability}" to be a known extension capability. Use canonical capability names (see manifest.capabilities).`);known.add(normalized)}return known},declared=[...toKnownCapabilitySet(expectation.declared,"declared")].sort((left,right)=>left.localeCompare(right)),allowUnused=toKnownCapabilitySet(expectation.allowUnused??[],"allowUnused"),used=collectUsedExtensionCapabilities(activation,{extensionName:expectation.extensionName}),usedSet=new Set(used),unused=declared.filter(capability=>!usedSet.has(capability)&&!allowUnused.has(capability));if(unused.length>0){const scopeSuffix=extensionNameSuffix(expectation.extensionName);throw new Error(`Expected every declared capability${scopeSuffix} to be exercised, but [${unused.join(", ")}] ${unused.length===1?"is":"are"} declared yet never registered against. Remove ${unused.length===1?"it":"them"} from manifest.capabilities for least privilege, or pass allowUnused for capabilities registered only behind a runtime flag.`)}return{declared,used,unused}}function assertExtensionBlueprint(blueprint,options={}){const result=lintExtensionBlueprint(blueprint,options);if(!result.ok){const errors=result.findings.filter(finding=>finding.severity==="error");throw new Error(`Extension blueprint failed preflight with ${errors.length} ${errors.length===1?"error":"errors"}:
2
+ `+errors.map(finding=>` - [${finding.code}] ${finding.message}`).join(`
3
+ `))}return result}function assertProjectProfile(profile,options={}){const report=lintProjectProfile(profile),blocking=report.findings.filter(finding=>finding.severity==="error"||options.strict===!0&&finding.severity==="warning");if(blocking.length>0)throw new Error(`Project profile "${report.profile}" failed lint with ${blocking.length} ${blocking.length===1?"issue":"issues"}:
4
+ `+blocking.map(finding=>` - ${finding.severity} [${finding.code}] ${finding.message}`).join(`
5
+ `));return report}function assertExtensionManifestMatchesBlueprint(manifest,blueprint){const declaredCapabilities=Array.isArray(manifest.capabilities)?manifest.capabilities:[],result=lintExtensionBlueprint(blueprint,{declaredCapabilities}),declared=result.declared,declaredSet=new Set(declared),usedSet=new Set(result.used),missing=result.used.filter(capability=>!declaredSet.has(capability)),unused=declared.filter(capability=>!usedSet.has(capability));if(missing.length>0||unused.length>0){const parts=[];throw missing.length>0&&parts.push(`missing [${missing.join(", ")}] (the blueprint registers ${missing.length===1?"a surface":"surfaces"} requiring ${missing.length===1?"it":"them"}; activation throws extension_capability_missing)`),unused.length>0&&parts.push(`unused [${unused.join(", ")}] (declared but no surface exercises ${unused.length===1?"it":"them"}; drop for least privilege)`),new Error(`Manifest capabilities do not match the blueprint: ${parts.join("; ")}. Set capabilities to synthesizeExtensionManifest(blueprint, identity).capabilities to stay in sync.`)}return{used:result.used,declared,missing,unused,findings:result.findings}}function assertExtensionManifestCompatible(manifest,target){const result=checkExtensionManifestCompatibility(manifest,target),blocking=result.findings.filter(finding=>finding.severity==="error");if(blocking.length>0)throw new Error(`Extension manifest is not compatible with pm ${result.pmVersion}: ${blocking.map(finding=>finding.message).join("; ")}`);return result}function assertExtensionPreflight(blueprint,options={}){const report=preflightExtension(blueprint,options);if(!report.ok){const errors=report.findings.filter(finding=>finding.severity==="error");throw new Error(`Extension failed preflight with ${errors.length} ${errors.length===1?"error":"errors"}:
6
+ `+errors.map(finding=>` - [${finding.source}:${finding.code}] ${finding.message}`).join(`
7
+ `))}return report}function assertTestModuleHasActivateExport(module){if(!resolveActivatablePropertyRecord(module))throw new Error("createExtensionTestHarness received a module with no activate export. Pass the extension module (with an activate(api) function on the module or its default export) as the first argument, and options second.")}async function createExtensionTestHarness(module,options={}){assertTestModuleHasActivateExport(module);const manifest=readTestExtensionManifest(module),name=resolveTestExtensionName(manifest,options.name),layer=options.layer??"project",activation=await activateExtensionForTest(module,options);if(activation.failed.length>0){const detail=activation.failed.map(failure=>{const missingCapability=failure.trace?.missing_capability,reason=missingCapability?`${failure.error}; missing capability "${missingCapability}"`:failure.error;return`${failure.layer}:${failure.name} (${reason})`}).join(", ");throw new Error(`createExtensionTestHarness could not activate the extension cleanly: ${detail}. Declare the required capability in the manifest (or pass it via options.capabilities), or use activateExtensionForTest directly to inspect a failed activation.`)}return{module,name,layer,activation,activationSummary(describeOptions){return describeExtensionActivation(activation,describeOptions)},renderMarkdown(markdownOptions={}){const{extensionName,...renderOptions}=markdownOptions??{};return renderExtensionSurfaceMarkdown(describeExtensionActivation(activation,{extensionName}),renderOptions)},assertCommandContract(expectation){return assertRegisteredCommandContract(activation.registrations,expectation)},assertFlags(expectation){return assertRegisteredFlags(activation.registrations,expectation)},assertItemField(expectation){return assertRegisteredItemField(activation.registrations,expectation)},assertItemType(expectation){return assertRegisteredItemType(activation.registrations,expectation)},assertProfile(expectation){return assertRegisteredProfile(activation.registrations,expectation)},assertHook(expectation){return assertRegisteredHook(activation.hooks,expectation)},assertCommandOverride(expectation){return assertRegisteredCommandOverride(activation.commands,expectation)},assertParserOverride(expectation){return assertRegisteredParserOverride(activation.parsers,expectation)},assertPreflightOverride(expectation){return assertRegisteredPreflightOverride(activation.preflight,expectation)},assertRendererOverride(expectation){return assertRegisteredRendererOverride(activation.renderers,expectation)},assertServiceOverride(expectation){return assertRegisteredServiceOverride(activation.services,expectation)},assertSearchProvider(expectation){return assertRegisteredSearchProvider(activation.registrations,expectation)},assertVectorStoreAdapter(expectation){return assertRegisteredVectorStoreAdapter(activation.registrations,expectation)},assertImporter(expectation){return assertRegisteredImporter(activation.registrations,expectation)},assertExporter(expectation){return assertRegisteredExporter(activation.registrations,expectation)},assertMigration(expectation){return assertRegisteredMigration(activation.registrations,expectation)},assertCapabilityUsage(expectation){return assertExtensionCapabilityUsage(activation,expectation)},runCommand(runOptions){return runRegisteredCommandForTest(activation.commands,runOptions)},runHook(runOptions){return runRegisteredHookForTest(activation.hooks,runOptions)},runMutationGuard(runOptions){return runRegisteredMutationGuardForTest(activation.hooks,runOptions)},runCommandOverride(context){return runRegisteredCommandOverrideForTest(activation.commands,context)},runParserOverride(context){return runRegisteredParserOverrideForTest(activation.parsers,context)},runPreflightOverride(context){return runRegisteredPreflightOverrideForTest(activation.preflight,context)},runRendererOverride(context){return runRegisteredRendererOverrideForTest(activation.renderers,context)},runServiceOverride(context){return runRegisteredServiceOverrideForTest(activation.services,context)},runSearchProvider(runOptions){return runRegisteredSearchProviderForTest(activation.registrations,runOptions)},runVectorStoreAdapter(runOptions){return runRegisteredVectorStoreAdapterForTest(activation.registrations,runOptions)},runMigration(runOptions){return runRegisteredMigrationForTest(activation.registrations,runOptions)},runImporter(runOptions){return runRegisteredImporterForTest(activation,runOptions)},runExporter(runOptions){return runRegisteredExporterForTest(activation,runOptions)},deactivate(deactivateOptions={}){return deactivateExtensionForTest(module,{name,layer,activation,deactivateTimeoutMs:deactivateOptions.deactivateTimeoutMs})}}}export{activateExtensionForTest,assertExtensionBlueprint,assertExtensionCapabilityUsage,assertExtensionDeactivated,assertExtensionManifestCompatible,assertExtensionManifestMatchesBlueprint,assertExtensionPreflight,assertPackageManifest,assertProjectProfile,assertRegisteredCommandContract,assertRegisteredCommandOverride,assertRegisteredExporter,assertRegisteredFlags,assertRegisteredHook,assertRegisteredImporter,assertRegisteredItemField,assertRegisteredItemType,assertRegisteredMigration,assertRegisteredParserOverride,assertRegisteredPreflightOverride,assertRegisteredProfile,assertRegisteredRendererOverride,assertRegisteredSearchProvider,assertRegisteredServiceOverride,assertRegisteredVectorStoreAdapter,createExtensionTestHarness,deactivateExtensionForTest,describeExtensionActivation,describeExtensionBlueprint,lintExtensionBlueprint,renderExtensionSurfaceMarkdown,runRegisteredCommandForTest,runRegisteredCommandOverrideForTest,runRegisteredExporterForTest,runRegisteredHookForTest,runRegisteredImporterForTest,runRegisteredMigrationForTest,runRegisteredMutationGuardForTest,runRegisteredParserOverrideForTest,runRegisteredPreflightOverrideForTest,runRegisteredRendererOverrideForTest,runRegisteredSearchProviderForTest,runRegisteredServiceOverrideForTest,runRegisteredVectorStoreAdapterForTest};
5
8
  //# sourceMappingURL=testing.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]="419a061f-e181-5b18-9e3a-d22cc5aff416")}catch(e2){}})();import{parseSourceLineRange}from"./source-traceability.js";function runtimeFilesLookupOptions(options,paths,parseInteger){let lineRange;if(typeof options.lines==="string"){lineRange=parseSourceLineRange(options.lines)}else if(options.lineRange!==void 0){if(options.lineRange===null||typeof options.lineRange!=="object"||Array.isArray(options.lineRange)){throw new RangeError("Source line range must be an object with numeric start and end values.")}lineRange=parseSourceLineRange(`${String(Reflect.get(options.lineRange,"start"))}:${String(Reflect.get(options.lineRange,"end"))}`)}return{paths,scope:options.scope==="project"||options.scope==="global"?options.scope:void 0,limit:parseInteger(options.limit,"files lookup limit"),offset:parseInteger(options.offset,"files lookup offset"),noTruncate:options.noTruncate===true,strictRead:options.strictRead===true,explain:options.explain===true,lineRange,decisionDepth:parseInteger(options.decisionDepth,"files lookup decision depth")}}export{runtimeFilesLookupOptions};
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]="920b5725-710a-5839-86e3-dbdbc8a602a8")}catch{}})();import{parseSourceLineRange}from"./source-traceability.js";function runtimeFilesLookupOptions(options,paths,parseInteger){let lineRange;if(typeof options.lines=="string")lineRange=parseSourceLineRange(options.lines);else if(options.lineRange!==void 0){if(options.lineRange===null||typeof options.lineRange!="object"||Array.isArray(options.lineRange))throw new RangeError("Source line range must be an object with numeric start and end values.");lineRange=parseSourceLineRange(`${String(Reflect.get(options.lineRange,"start"))}:${String(Reflect.get(options.lineRange,"end"))}`)}return{paths,scope:options.scope==="project"||options.scope==="global"?options.scope:void 0,limit:parseInteger(options.limit,"files lookup limit"),offset:parseInteger(options.offset,"files lookup offset"),noTruncate:options.noTruncate===!0,strictRead:options.strictRead===!0,explain:options.explain===!0,lineRange,decisionDepth:parseInteger(options.decisionDepth,"files lookup decision depth")}}export{runtimeFilesLookupOptions};
2
2
  //# sourceMappingURL=runtime-files-lookup.js.map
@@ -1,2 +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]="1d4534aa-5a56-5a76-8971-aa3ba6c52e59")}catch(e2){}})();import{execFile}from"node:child_process";import path from"node:path";import{assembleWorkspaceRelationshipGraph}from"../graph/assembly.js";function runGit(workspaceRoot,args){return new Promise((resolve,reject)=>{execFile("git",[...args],{cwd:workspaceRoot,encoding:"utf8",maxBuffer:4*1024*1024},(error,stdout)=>{if(error)reject(error);else resolve(stdout)})})}function validateLineRange(range){if(range&&(!Number.isSafeInteger(range.start)||!Number.isSafeInteger(range.end)||range.start<1||range.end<range.start)){throw new RangeError("Source line range must be inclusive positive integers with end >= start.")}}function parseSourceLineRange(value){const match=/^(\d+):(\d+)$/u.exec(value.trim());const range=match?{start:Number(match[1]),end:Number(match[2])}:void 0;validateLineRange(range);if(!range){throw new RangeError("Source line range must use start:end.")}return range}function parseBlameCommits(output){const lines=new Map;for(const row of output.split("\n")){const commit=/^([0-9a-f^]{40,64}) \d+ \d+(?: \d+)?$/u.exec(row)?.[1];if(commit)lines.set(commit,(lines.get(commit)??0)+1)}return lines}function parseCommitItemReferences(output){const fields=output.split("\0");const references=new Map;for(let index=0;index+1<fields.length;index+=2){const commit=fields[index]?.trim();if(!commit)continue;const ids=[...new Set(fields[index+1]?.match(/\bpm-[a-z0-9][a-z0-9-]{2,63}\b/gu)??[])].sort((left,right)=>left.localeCompare(right));references.set(commit,ids)}return references}async function readGitAttribution(params){const relativePath=path.relative(params.workspaceRoot,path.resolve(params.workspaceRoot,params.sourcePath));const blame=await runGit(params.workspaceRoot,["blame","--line-porcelain","-L",`${params.lineRange.start},${params.lineRange.end}`,"--",relativePath]);const log=await runGit(params.workspaceRoot,["log","-n","256","--format=%H%x00%B%x00","--",relativePath]);return{commitLines:parseBlameCommits(blame),commitItems:parseCommitItemReferences(log),available:true}}function expandDecisionPath(params){const tail=params.current.nodes.at(-1);const nextDepth=params.current.kinds.length+1;let foundDepth;for(const edge of params.graph.incidentEdges(tail)){const outgoing=edge.source===tail;const next=outgoing?edge.target:edge.source;if((params.visitedDepth.get(next)??Number.POSITIVE_INFINITY)<nextDepth)continue;params.visitedDepth.set(next,nextDepth);const definition=params.graph.registry().require(edge.kind);const nextPath={nodes:[...params.current.nodes,next],kinds:[...params.current.kinds,outgoing?edge.kind:definition.inverse??edge.kind]};if(params.details.get(next)?.type?.toLowerCase()==="decision"){foundDepth=nextDepth;params.found.push(nextPath)}else{params.queue.push(nextPath)}}return foundDepth}function collectDecisionPaths(params){const queue=[{nodes:[params.itemId],kinds:[]}];const visitedDepth=new Map([[params.itemId,0]]);const found=[];let foundDepth;while(queue.length>0){const current=queue.shift();const depth=current.kinds.length;if(foundDepth!==void 0&&depth>=foundDepth)continue;if(depth>=params.maxDepth)continue;foundDepth=expandDecisionPath({current,graph:params.graph,details:params.details,visitedDepth,queue,found})??foundDepth}found.sort((left,right)=>left.nodes.join("\0").localeCompare(right.nodes.join("\0")));return found}function shortestDecisionPath(itemId,corpus,maxDepth){const assembly=assembleWorkspaceRelationshipGraph(corpus);if(!assembly.graph.hasNode(itemId)){return{status:"not_found",nodes:[],kinds:[],alternative_decision_ids:[]}}const found=collectDecisionPaths({itemId,maxDepth,graph:assembly.graph,details:new Map(assembly.details.map(detail=>[detail.id,detail]))});const selected=found[0];if(!selected){return{status:"not_found",nodes:[],kinds:[],alternative_decision_ids:[]}}const decisionIds=[...new Set(found.map(entry=>entry.nodes.at(-1)))];return{status:decisionIds.length===1?"found":"ambiguous",nodes:selected.nodes,kinds:selected.kinds,alternative_decision_ids:decisionIds.slice(1)}}async function resolveGitAttribution(params){if(!params.lineRange){return{commitLines:new Map,commitItems:new Map,available:true}}try{return await readGitAttribution({workspaceRoot:params.workspaceRoot,sourcePath:params.paths[0],lineRange:params.lineRange})}catch{return{commitLines:new Map,commitItems:new Map,available:false}}}function sourceAmbiguities(params){const ambiguities=[];if(params.hasLineRange&&!params.attributionAvailable){ambiguities.push("git_attribution_unavailable")}if(params.hasLineRange&&params.contributionLines===0){ambiguities.push("line_attribution_unmapped")}if(params.decisionStatus==="ambiguous"){ambiguities.push("multiple_governing_decisions")}if(params.decisionStatus==="not_found"){ambiguities.push("governing_decision_not_found")}return ambiguities}function mappedBlamedCommits(attribution){return[...attribution.commitLines.keys()].filter(commit=>(attribution.commitItems.get(commit)?.length??0)>0)}async function explainSourceTraceability(params){validateLineRange(params.lineRange);const decisionDepth=params.decisionDepth??8;if(!Number.isSafeInteger(decisionDepth)||decisionDepth<1||decisionDepth>32){throw new RangeError("Decision path depth must be an integer from 1 to 32.")}const attribution=await resolveGitAttribution(params);const mappedCommits=mappedBlamedCommits(attribution);const explanations=new Map;for(const candidate of params.candidates){const attributedCommits=[...attribution.commitLines.entries()].filter(([commit])=>attribution.commitItems.get(commit)?.includes(candidate.item.id));const contributionLines=attributedCommits.reduce((total,[,lines])=>total+lines,0);const decisionPath=shortestDecisionPath(candidate.item.id,params.corpus,decisionDepth);const ambiguities=sourceAmbiguities({hasLineRange:params.lineRange!==void 0,attributionAvailable:attribution.available,contributionLines,decisionStatus:decisionPath.status});explanations.set(candidate.item.id,{score:contributionLines*100+candidate.files.length*10+Math.max(0,9-Math.floor((Date.now()-Date.parse(candidate.item.updated_at))/(30*24*60*60*1e3))),contribution_lines:contributionLines,evidence:[...candidate.files.map(file=>({kind:"linked_file",reference:file.path})),...attributedCommits.map(([commit,lines])=>({kind:"git_commit",reference:commit.slice(0,12),contribution_lines:lines}))],rationale:{value:candidate.item.value?.trim()||null,why_now:candidate.item.why_now?.trim()||null,outcome:candidate.item.outcome?.trim()||null,objective:candidate.item.objective?.trim()||null},decision_path:decisionPath,ambiguities})}return{explanations,receipt:{line_range:params.lineRange??null,blamed_commit_count:attribution.commitLines.size,mapped_commit_count:mappedCommits.length,unmapped_commit_count:attribution.commitLines.size-mappedCommits.length,decision_depth:decisionDepth}}}const _testOnlySourceTraceability={mappedBlamedCommits,parseBlameCommits,parseCommitItemReferences,shortestDecisionPath};export{_testOnlySourceTraceability,explainSourceTraceability,parseSourceLineRange};
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]="3bb613e2-51f9-5947-8d92-d6207bb62cdc")}catch{}})();import{execFile}from"node:child_process";import path from"node:path";import{assembleWorkspaceRelationshipGraph}from"../graph/assembly.js";function runGit(workspaceRoot,args){return new Promise((resolve,reject)=>{execFile("git",[...args],{cwd:workspaceRoot,encoding:"utf8",maxBuffer:4*1024*1024},(error,stdout)=>{error?reject(error):resolve(stdout)})})}function validateLineRange(range){if(range&&(!Number.isSafeInteger(range.start)||!Number.isSafeInteger(range.end)||range.start<1||range.end<range.start))throw new RangeError("Source line range must be inclusive positive integers with end >= start.")}function parseSourceLineRange(value){const match=/^(\d+):(\d+)$/u.exec(value.trim()),range=match?{start:Number(match[1]),end:Number(match[2])}:void 0;if(validateLineRange(range),!range)throw new RangeError("Source line range must use start:end.");return range}function parseBlameCommits(output){const lines=new Map;for(const row of output.split(`
2
+ `)){const commit=/^([0-9a-f^]{40,64}) \d+ \d+(?: \d+)?$/u.exec(row)?.[1];commit&&lines.set(commit,(lines.get(commit)??0)+1)}return lines}function parseCommitItemReferences(output){const fields=output.split("\0"),references=new Map;for(let index=0;index+1<fields.length;index+=2){const commit=fields[index]?.trim();if(!commit)continue;const ids=[...new Set(fields[index+1]?.match(/\bpm-[a-z0-9][a-z0-9-]{2,63}\b/gu)??[])].sort((left,right)=>left.localeCompare(right));references.set(commit,ids)}return references}async function readGitAttribution(params){const relativePath=path.relative(params.workspaceRoot,path.resolve(params.workspaceRoot,params.sourcePath)),blame=await runGit(params.workspaceRoot,["blame","--line-porcelain","-L",`${params.lineRange.start},${params.lineRange.end}`,"--",relativePath]),log=await runGit(params.workspaceRoot,["log","-n","256","--format=%H%x00%B%x00","--",relativePath]);return{commitLines:parseBlameCommits(blame),commitItems:parseCommitItemReferences(log),available:!0}}function expandDecisionPath(params){const tail=params.current.nodes.at(-1),nextDepth=params.current.kinds.length+1;let foundDepth;for(const edge of params.graph.incidentEdges(tail)){const outgoing=edge.source===tail,next=outgoing?edge.target:edge.source;if((params.visitedDepth.get(next)??Number.POSITIVE_INFINITY)<nextDepth)continue;params.visitedDepth.set(next,nextDepth);const definition=params.graph.registry().require(edge.kind),nextPath={nodes:[...params.current.nodes,next],kinds:[...params.current.kinds,outgoing?edge.kind:definition.inverse??edge.kind]};params.details.get(next)?.type?.toLowerCase()==="decision"?(foundDepth=nextDepth,params.found.push(nextPath)):params.queue.push(nextPath)}return foundDepth}function collectDecisionPaths(params){const queue=[{nodes:[params.itemId],kinds:[]}],visitedDepth=new Map([[params.itemId,0]]),found=[];let foundDepth;for(;queue.length>0;){const current=queue.shift(),depth=current.kinds.length;foundDepth!==void 0&&depth>=foundDepth||depth>=params.maxDepth||(foundDepth=expandDecisionPath({current,graph:params.graph,details:params.details,visitedDepth,queue,found})??foundDepth)}return found.sort((left,right)=>left.nodes.join("\0").localeCompare(right.nodes.join("\0"))),found}function shortestDecisionPath(itemId,corpus,maxDepth){const assembly=assembleWorkspaceRelationshipGraph(corpus);if(!assembly.graph.hasNode(itemId))return{status:"not_found",nodes:[],kinds:[],alternative_decision_ids:[]};const found=collectDecisionPaths({itemId,maxDepth,graph:assembly.graph,details:new Map(assembly.details.map(detail=>[detail.id,detail]))}),selected=found[0];if(!selected)return{status:"not_found",nodes:[],kinds:[],alternative_decision_ids:[]};const decisionIds=[...new Set(found.map(entry=>entry.nodes.at(-1)))];return{status:decisionIds.length===1?"found":"ambiguous",nodes:selected.nodes,kinds:selected.kinds,alternative_decision_ids:decisionIds.slice(1)}}async function resolveGitAttribution(params){if(!params.lineRange)return{commitLines:new Map,commitItems:new Map,available:!0};try{return await readGitAttribution({workspaceRoot:params.workspaceRoot,sourcePath:params.paths[0],lineRange:params.lineRange})}catch{return{commitLines:new Map,commitItems:new Map,available:!1}}}function sourceAmbiguities(params){const ambiguities=[];return params.hasLineRange&&!params.attributionAvailable&&ambiguities.push("git_attribution_unavailable"),params.hasLineRange&&params.contributionLines===0&&ambiguities.push("line_attribution_unmapped"),params.decisionStatus==="ambiguous"&&ambiguities.push("multiple_governing_decisions"),params.decisionStatus==="not_found"&&ambiguities.push("governing_decision_not_found"),ambiguities}function mappedBlamedCommits(attribution){return[...attribution.commitLines.keys()].filter(commit=>(attribution.commitItems.get(commit)?.length??0)>0)}async function explainSourceTraceability(params){validateLineRange(params.lineRange);const decisionDepth=params.decisionDepth??8;if(!Number.isSafeInteger(decisionDepth)||decisionDepth<1||decisionDepth>32)throw new RangeError("Decision path depth must be an integer from 1 to 32.");const attribution=await resolveGitAttribution(params),mappedCommits=mappedBlamedCommits(attribution),explanations=new Map;for(const candidate of params.candidates){const attributedCommits=[...attribution.commitLines.entries()].filter(([commit])=>attribution.commitItems.get(commit)?.includes(candidate.item.id)),contributionLines=attributedCommits.reduce((total,[,lines])=>total+lines,0),decisionPath=shortestDecisionPath(candidate.item.id,params.corpus,decisionDepth),ambiguities=sourceAmbiguities({hasLineRange:params.lineRange!==void 0,attributionAvailable:attribution.available,contributionLines,decisionStatus:decisionPath.status});explanations.set(candidate.item.id,{score:contributionLines*100+candidate.files.length*10+Math.max(0,9-Math.floor((Date.now()-Date.parse(candidate.item.updated_at))/(720*60*60*1e3))),contribution_lines:contributionLines,evidence:[...candidate.files.map(file=>({kind:"linked_file",reference:file.path})),...attributedCommits.map(([commit,lines])=>({kind:"git_commit",reference:commit.slice(0,12),contribution_lines:lines}))],rationale:{value:candidate.item.value?.trim()||null,why_now:candidate.item.why_now?.trim()||null,outcome:candidate.item.outcome?.trim()||null,objective:candidate.item.objective?.trim()||null},decision_path:decisionPath,ambiguities})}return{explanations,receipt:{line_range:params.lineRange??null,blamed_commit_count:attribution.commitLines.size,mapped_commit_count:mappedCommits.length,unmapped_commit_count:attribution.commitLines.size-mappedCommits.length,decision_depth:decisionDepth}}}const _testOnlySourceTraceability={mappedBlamedCommits,parseBlameCommits,parseCommitItemReferences,shortestDecisionPath};export{_testOnlySourceTraceability,explainSourceTraceability,parseSourceLineRange};
2
3
  //# sourceMappingURL=source-traceability.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]="bd9a8d3b-bc6f-5309-a3fb-7e5f41ef9dab")}catch(e2){}})();import{discoverNearbyPmRoot}from"../core/store/paths.js";export{discoverNearbyPmRoot};
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]="bd9a8d3b-bc6f-5309-a3fb-7e5f41ef9dab")}catch{}})();import{discoverNearbyPmRoot}from"../core/store/paths.js";export{discoverNearbyPmRoot};
2
2
  //# sourceMappingURL=tracker-root-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]="e8137f8b-745a-5ef5-9e7e-14b7d032c1ea")}catch(e2){}})();const WORKSPACE_CONTRACTS_CACHE_LIMIT=50;const workspaceExtensionRegistrationsCache=new Map;function clearWorkspaceContractsCache(){workspaceExtensionRegistrationsCache.clear()}function memoizeWorkspaceExtensionRegistrations(cacheKey,loadRegistrations){const cached=workspaceExtensionRegistrationsCache.get(cacheKey);if(cached!==void 0){return cached}if(workspaceExtensionRegistrationsCache.size>=WORKSPACE_CONTRACTS_CACHE_LIMIT){const oldestKey=workspaceExtensionRegistrationsCache.keys().next().value;workspaceExtensionRegistrationsCache.delete(oldestKey)}const registrations=loadRegistrations().catch(error=>{if(workspaceExtensionRegistrationsCache.get(cacheKey)===registrations){workspaceExtensionRegistrationsCache.delete(cacheKey)}throw error});workspaceExtensionRegistrationsCache.set(cacheKey,registrations);return registrations}export{clearWorkspaceContractsCache,memoizeWorkspaceExtensionRegistrations};
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]="96234a42-d25c-5221-a12b-a992925a13ba")}catch{}})();const WORKSPACE_CONTRACTS_CACHE_LIMIT=50,workspaceExtensionRegistrationsCache=new Map;function clearWorkspaceContractsCache(){workspaceExtensionRegistrationsCache.clear()}function memoizeWorkspaceExtensionRegistrations(cacheKey,loadRegistrations){const cached=workspaceExtensionRegistrationsCache.get(cacheKey);if(cached!==void 0)return cached;if(workspaceExtensionRegistrationsCache.size>=50){const oldestKey=workspaceExtensionRegistrationsCache.keys().next().value;workspaceExtensionRegistrationsCache.delete(oldestKey)}const registrations=loadRegistrations().catch(error=>{throw workspaceExtensionRegistrationsCache.get(cacheKey)===registrations&&workspaceExtensionRegistrationsCache.delete(cacheKey),error});return workspaceExtensionRegistrationsCache.set(cacheKey,registrations),registrations}export{clearWorkspaceContractsCache,memoizeWorkspaceExtensionRegistrations};
2
2
  //# sourceMappingURL=workspace-contracts-cache.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]="0c84b11c-502f-5c33-a757-5757402357b4")}catch(e2){}})();import{runtimeFieldOptionTarget}from"../core/schema/runtime-schema.js";function buildWorkspaceFieldContracts(definitions){return definitions.map(definition=>({key:definition.key,optionName:runtimeFieldOptionTarget(definition),metadataKey:definition.metadata_key,type:definition.type,commands:[...definition.commands],repeatable:definition.repeatable,requiredOnCreate:definition.required_on_create,...definition.description?{description:definition.description}:{}}))}function buildWorkspaceExtensionCommandContracts(definitions){return definitions.map(definition=>({command:definition.command,action:definition.action,arguments:definition.arguments.map(argument=>({name:argument.name,required:argument.required===true,variadic:argument.variadic===true,description:argument.description})),description:definition.description,tier:definition.tier??"standard",family:definition.family??"extensions"}))}export{buildWorkspaceExtensionCommandContracts,buildWorkspaceFieldContracts};
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]="69f9c792-7ee1-5e4b-9900-38e1c887c4d4")}catch{}})();import{runtimeFieldOptionTarget}from"../core/schema/runtime-schema.js";function buildWorkspaceFieldContracts(definitions){return definitions.map(definition=>({key:definition.key,optionName:runtimeFieldOptionTarget(definition),metadataKey:definition.metadata_key,type:definition.type,commands:[...definition.commands],repeatable:definition.repeatable,requiredOnCreate:definition.required_on_create,...definition.description?{description:definition.description}:{}}))}function buildWorkspaceExtensionCommandContracts(definitions){return definitions.map(definition=>({command:definition.command,action:definition.action,arguments:definition.arguments.map(argument=>({name:argument.name,required:argument.required===!0,variadic:argument.variadic===!0,description:argument.description})),description:definition.description,tier:definition.tier??"standard",family:definition.family??"extensions"}))}export{buildWorkspaceExtensionCommandContracts,buildWorkspaceFieldContracts};
2
2
  //# sourceMappingURL=workspace-contracts.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]="51bac04a-5a6e-53b3-806f-fa0bf6f8e7b4")}catch(e2){}})();import path from"node:path";import{createHash}from"node:crypto";import{isFileAbsentError,writeFileAtomic}from"../core/fs/fs-utils.js";import{normalizeStatusForRegistry}from"../core/item/status.js";import{stableStringify}from"../core/shared/serialization.js";import{readItemMetadataDerivedIndexState}from"../core/store/item-metadata-cache.js";import{resolveCompletionTimestamp}from"./lifecycle-completion.js";import fs from"node:fs/promises";const WORKSPACE_MEMORY_FORMAT_VERSION=1;const DEFAULT_WORKSPACE_MEMORY_MINIMUM_ITEMS=1e4;const DEFAULT_ROLLUP_LIMIT=12;function quarterKey(timestamp){const date=new Date(timestamp);return`${date.getUTCFullYear()}-Q${Math.floor(date.getUTCMonth()/3)+1}`}function nearestEpic(item,itemsById){const visited=new Set;let parentId=item.parent;while(parentId&&!visited.has(parentId)){visited.add(parentId);const parent=itemsById.get(parentId);if(!parent)return void 0;if(parent.type.toLowerCase()==="epic")return parent;parentId=parent.parent}return void 0}function finalizeRollup(rollup){const ordered=[...rollup.items].sort((left,right)=>{const timestampOrder=right.completion.timestamp.localeCompare(left.completion.timestamp);return timestampOrder||left.item.id.localeCompare(right.item.id)});const outcomes=new Set;let knowledgeEntries=0;for(const{item}of ordered){const outcome=item.resolution??item.close_reason;if(outcome?.trim())outcomes.add(outcome.trim());knowledgeEntries+=(item.notes?.length??0)+(item.learnings?.length??0)}return{kind:rollup.kind,key:rollup.key,label:rollup.label,item_count:ordered.length,first_closed_at:ordered.at(-1).completion.timestamp,last_closed_at:ordered[0].completion.timestamp,representative_items:ordered.slice(0,5).map(({item:{id,title}})=>({id,title})),outcomes:[...outcomes].sort().slice(0,5),knowledge_entries:knowledgeEntries}}function buildWorkspaceMemorySnapshot(items,options){if(!options.sourceCursor.trim()){throw new TypeError("Workspace memory source cursor must be non-empty")}if(!Number.isFinite(Date.parse(options.now))){throw new TypeError("Workspace memory clock must be a valid timestamp")}const completed=items.filter(item=>options.statusRegistry.terminal_done_statuses.has(normalizeStatusForRegistry(item.status,options.statusRegistry))).map(item=>{const completion=resolveCompletionTimestamp(item);if(!completion.resolved){throw new TypeError(`Completed item ${item.id} has no reporting timestamp`)}return{item,completion}});const itemsById=new Map(items.map(item=>[item.id,item]));const groups=new Map;for(const completedItem of completed){const{item,completion}=completedItem;const epoch=quarterKey(completion.timestamp);const epochKey=`epoch:${epoch}`;const epochRollup=groups.get(epochKey)??{kind:"epoch",key:epoch,label:epoch,items:[]};epochRollup.items.push(completedItem);groups.set(epochKey,epochRollup);const epic=nearestEpic(item,itemsById);if(epic){const epicKey=`epic:${epic.id}`;const epicRollup=groups.get(epicKey)??{kind:"epic",key:epic.id,label:epic.title,items:[]};epicRollup.items.push(completedItem);groups.set(epicKey,epicRollup)}}return{format_version:WORKSPACE_MEMORY_FORMAT_VERSION,source_cursor:options.sourceCursor,source_item_count:items.length,generated_at:options.now,completion_time_sources:completed.reduce((counts,{completion})=>{counts[completion.source]+=1;return counts},{completed_at:0,closed_at:0,updated_at:0}),rollups:[...groups.values()].map(finalizeRollup).sort((left,right)=>right.last_closed_at.localeCompare(left.last_closed_at)||left.kind.localeCompare(right.kind)||left.key.localeCompare(right.key))}}function isWorkspaceMemoryItemReference(value){return typeof value==="object"&&value!==null&&"id"in value&&typeof value.id==="string"&&value.id.length>0&&"title"in value&&typeof value.title==="string"}function isWorkspaceMemoryRollup(value){if(typeof value!=="object"||value===null)return false;const rollup=value;const textFields=[rollup.key,rollup.label].every(field=>typeof field==="string"&&field.length>0);const timestamps=[rollup.first_closed_at,rollup.last_closed_at].every(timestamp=>typeof timestamp==="string"&&Number.isFinite(Date.parse(timestamp)));return(rollup.kind==="epoch"||rollup.kind==="epic")&&textFields&&Number.isSafeInteger(rollup.item_count)&&rollup.item_count>0&&timestamps&&Array.isArray(rollup.representative_items)&&rollup.representative_items.every(isWorkspaceMemoryItemReference)&&Array.isArray(rollup.outcomes)&&rollup.outcomes.every(outcome=>typeof outcome==="string")&&Number.isSafeInteger(rollup.knowledge_entries)&&rollup.knowledge_entries>=0}function parseWorkspaceMemorySnapshot(value){if(typeof value!=="object"||value===null||Array.isArray(value)){return null}const snapshot=value;if(snapshot.format_version!==WORKSPACE_MEMORY_FORMAT_VERSION||typeof snapshot.source_cursor!=="string"||!snapshot.source_cursor.trim()||!Number.isSafeInteger(snapshot.source_item_count)||snapshot.source_item_count<0||typeof snapshot.generated_at!=="string"||!Number.isFinite(Date.parse(snapshot.generated_at))||!Array.isArray(snapshot.rollups)){return null}const valid=snapshot.rollups.every(isWorkspaceMemoryRollup);return valid?snapshot:null}function fallbackSourceCursor(items){return`scan:${createHash("sha256").update(stableStringify(items.map(item=>[item.id,item.updated_at,item.status,item.parent]).sort(([left],[right])=>String(left).localeCompare(String(right))))).digest("hex")}`}async function resolveWorkspaceMemorySourceCursor(items,pmRoot,explicitCursor){if(explicitCursor!==void 0)return explicitCursor;const indexState=await readItemMetadataDerivedIndexState(pmRoot);return indexState?.source_cursor??fallbackSourceCursor(items)}async function readPersistedWorkspaceMemory(filePath){try{const snapshot=parseWorkspaceMemorySnapshot(JSON.parse(await fs.readFile(filePath,"utf8")));return{snapshot,invalid:snapshot===null}}catch(error){const missing=typeof error==="object"&&error!==null&&"code"in error&&isFileAbsentError(error);return{snapshot:null,invalid:!missing}}}async function readWorkspaceMemory(items,options){const minimumItems=Math.max(1,Math.floor(options.minimumItems??DEFAULT_WORKSPACE_MEMORY_MINIMUM_ITEMS));if(items.length<minimumItems){return{snapshot:null,cache_status:"skipped",warnings:[]}}const sourceCursor=await resolveWorkspaceMemorySourceCursor(items,options.pmRoot,options.sourceCursor);const filePath=path.join(options.pmRoot,"runtime","workspace-memory.json");const warnings=[];const persisted=await readPersistedWorkspaceMemory(filePath);const parsed=persisted.snapshot;if(persisted.invalid)warnings.push("workspace_memory_invalid");if(parsed?.source_cursor===sourceCursor&&parsed.source_item_count===items.length){return{snapshot:parsed,cache_status:"fresh",warnings}}if(parsed)warnings.push("workspace_memory_stale");const snapshot=buildWorkspaceMemorySnapshot(items,{statusRegistry:options.statusRegistry,sourceCursor,now:options.now});try{await writeFileAtomic(filePath,`${JSON.stringify(snapshot)}
2
- `)}catch{warnings.push("workspace_memory_write_failed")}return{snapshot,cache_status:"rebuilt",warnings}}function selectWorkspaceMemoryRollups(snapshot,tokenBudget,limit=DEFAULT_ROLLUP_LIMIT){const boundedBudget=Math.max(0,Math.floor(tokenBudget));let consumed=0;const selected=[];for(const rollup of snapshot.rollups){if(selected.length>=Math.max(0,Math.floor(limit)))break;const tokens=Math.ceil(JSON.stringify(rollup).length/4);if(consumed+tokens>boundedBudget)continue;selected.push(rollup);consumed+=tokens}return selected}function selectWorkspaceMemory(memory,tokenBudget,limit=DEFAULT_ROLLUP_LIMIT){if(memory.snapshot===null)return void 0;const rollups=selectWorkspaceMemoryRollups(memory.snapshot,tokenBudget,limit);if(rollups.length===0)return void 0;return{cache_status:memory.cache_status==="fresh"?"fresh":"rebuilt",source_cursor:memory.snapshot.source_cursor,...memory.snapshot.completion_time_sources?{completion_time_sources:{...memory.snapshot.completion_time_sources}}:{},rollups}}function searchWorkspaceMemory(snapshot,query,limit=5){if(snapshot===null)return[];const tokens=query.trim().toLowerCase().split(/\s+/u).filter(Boolean);if(tokens.length===0)return[];return snapshot.rollups.map(rollup=>({rollup,score:tokens.filter(token=>[rollup.key,rollup.label,...rollup.outcomes,...rollup.representative_items.flatMap(item=>[item.id,item.title])].join(" ").toLowerCase().includes(token)).length})).filter(({score})=>score>0).sort((left,right)=>right.score-left.score||right.rollup.last_closed_at.localeCompare(left.rollup.last_closed_at)||left.rollup.key.localeCompare(right.rollup.key)).slice(0,Math.max(0,Math.floor(limit))).map(({rollup})=>rollup)}function searchWorkspaceMemoryReadResult(memory,query,limit=5){const matches=searchWorkspaceMemory(memory.snapshot,query,limit);if(matches.length===0)return void 0;return{cache_status:memory.cache_status==="fresh"?"fresh":"rebuilt",matches}}export{DEFAULT_WORKSPACE_MEMORY_MINIMUM_ITEMS,buildWorkspaceMemorySnapshot,readWorkspaceMemory,searchWorkspaceMemory,searchWorkspaceMemoryReadResult,selectWorkspaceMemory,selectWorkspaceMemoryRollups};
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]="df753f1d-cfc1-555e-a411-e1417eab0b53")}catch{}})();import path from"node:path";import{createHash}from"node:crypto";import{isFileAbsentError,writeFileAtomic}from"../core/fs/fs-utils.js";import{normalizeStatusForRegistry}from"../core/item/status.js";import{stableStringify}from"../core/shared/serialization.js";import{readItemMetadataDerivedIndexState}from"../core/store/item-metadata-cache.js";import{resolveCompletionTimestamp}from"./lifecycle-completion.js";import fs from"node:fs/promises";const WORKSPACE_MEMORY_FORMAT_VERSION=1,DEFAULT_WORKSPACE_MEMORY_MINIMUM_ITEMS=1e4,DEFAULT_ROLLUP_LIMIT=12;function quarterKey(timestamp){const date=new Date(timestamp);return`${date.getUTCFullYear()}-Q${Math.floor(date.getUTCMonth()/3)+1}`}function nearestEpic(item,itemsById){const visited=new Set;let parentId=item.parent;for(;parentId&&!visited.has(parentId);){visited.add(parentId);const parent=itemsById.get(parentId);if(!parent)return;if(parent.type.toLowerCase()==="epic")return parent;parentId=parent.parent}}function finalizeRollup(rollup){const ordered=[...rollup.items].sort((left,right)=>right.completion.timestamp.localeCompare(left.completion.timestamp)||left.item.id.localeCompare(right.item.id)),outcomes=new Set;let knowledgeEntries=0;for(const{item}of ordered){const outcome=item.resolution??item.close_reason;outcome?.trim()&&outcomes.add(outcome.trim()),knowledgeEntries+=(item.notes?.length??0)+(item.learnings?.length??0)}return{kind:rollup.kind,key:rollup.key,label:rollup.label,item_count:ordered.length,first_closed_at:ordered.at(-1).completion.timestamp,last_closed_at:ordered[0].completion.timestamp,representative_items:ordered.slice(0,5).map(({item:{id,title}})=>({id,title})),outcomes:[...outcomes].sort().slice(0,5),knowledge_entries:knowledgeEntries}}function buildWorkspaceMemorySnapshot(items,options){if(!options.sourceCursor.trim())throw new TypeError("Workspace memory source cursor must be non-empty");if(!Number.isFinite(Date.parse(options.now)))throw new TypeError("Workspace memory clock must be a valid timestamp");const completed=items.filter(item=>options.statusRegistry.terminal_done_statuses.has(normalizeStatusForRegistry(item.status,options.statusRegistry))).map(item=>{const completion=resolveCompletionTimestamp(item);if(!completion.resolved)throw new TypeError(`Completed item ${item.id} has no reporting timestamp`);return{item,completion}}),itemsById=new Map(items.map(item=>[item.id,item])),groups=new Map;for(const completedItem of completed){const{item,completion}=completedItem,epoch=quarterKey(completion.timestamp),epochKey=`epoch:${epoch}`,epochRollup=groups.get(epochKey)??{kind:"epoch",key:epoch,label:epoch,items:[]};epochRollup.items.push(completedItem),groups.set(epochKey,epochRollup);const epic=nearestEpic(item,itemsById);if(epic){const epicKey=`epic:${epic.id}`,epicRollup=groups.get(epicKey)??{kind:"epic",key:epic.id,label:epic.title,items:[]};epicRollup.items.push(completedItem),groups.set(epicKey,epicRollup)}}return{format_version:WORKSPACE_MEMORY_FORMAT_VERSION,source_cursor:options.sourceCursor,source_item_count:items.length,generated_at:options.now,completion_time_sources:completed.reduce((counts,{completion})=>(counts[completion.source]+=1,counts),{completed_at:0,closed_at:0,updated_at:0}),rollups:[...groups.values()].map(finalizeRollup).sort((left,right)=>right.last_closed_at.localeCompare(left.last_closed_at)||left.kind.localeCompare(right.kind)||left.key.localeCompare(right.key))}}function isWorkspaceMemoryItemReference(value){return typeof value=="object"&&value!==null&&"id"in value&&typeof value.id=="string"&&value.id.length>0&&"title"in value&&typeof value.title=="string"}function isWorkspaceMemoryRollup(value){if(typeof value!="object"||value===null)return!1;const rollup=value,textFields=[rollup.key,rollup.label].every(field=>typeof field=="string"&&field.length>0),timestamps=[rollup.first_closed_at,rollup.last_closed_at].every(timestamp=>typeof timestamp=="string"&&Number.isFinite(Date.parse(timestamp)));return(rollup.kind==="epoch"||rollup.kind==="epic")&&textFields&&Number.isSafeInteger(rollup.item_count)&&rollup.item_count>0&&timestamps&&Array.isArray(rollup.representative_items)&&rollup.representative_items.every(isWorkspaceMemoryItemReference)&&Array.isArray(rollup.outcomes)&&rollup.outcomes.every(outcome=>typeof outcome=="string")&&Number.isSafeInteger(rollup.knowledge_entries)&&rollup.knowledge_entries>=0}function parseWorkspaceMemorySnapshot(value){if(typeof value!="object"||value===null||Array.isArray(value))return null;const snapshot=value;return snapshot.format_version!==WORKSPACE_MEMORY_FORMAT_VERSION||typeof snapshot.source_cursor!="string"||!snapshot.source_cursor.trim()||!Number.isSafeInteger(snapshot.source_item_count)||snapshot.source_item_count<0||typeof snapshot.generated_at!="string"||!Number.isFinite(Date.parse(snapshot.generated_at))||!Array.isArray(snapshot.rollups)?null:snapshot.rollups.every(isWorkspaceMemoryRollup)?snapshot:null}function fallbackSourceCursor(items){return`scan:${createHash("sha256").update(stableStringify(items.map(item=>[item.id,item.updated_at,item.status,item.parent]).sort(([left],[right])=>String(left).localeCompare(String(right))))).digest("hex")}`}async function resolveWorkspaceMemorySourceCursor(items,pmRoot,explicitCursor){return explicitCursor!==void 0?explicitCursor:(await readItemMetadataDerivedIndexState(pmRoot))?.source_cursor??fallbackSourceCursor(items)}async function readPersistedWorkspaceMemory(filePath){try{const snapshot=parseWorkspaceMemorySnapshot(JSON.parse(await fs.readFile(filePath,"utf8")));return{snapshot,invalid:snapshot===null}}catch(error){return{snapshot:null,invalid:!(typeof error=="object"&&error!==null&&"code"in error&&isFileAbsentError(error))}}}async function readWorkspaceMemory(items,options){const minimumItems=Math.max(1,Math.floor(options.minimumItems??DEFAULT_WORKSPACE_MEMORY_MINIMUM_ITEMS));if(items.length<minimumItems)return{snapshot:null,cache_status:"skipped",warnings:[]};const sourceCursor=await resolveWorkspaceMemorySourceCursor(items,options.pmRoot,options.sourceCursor),filePath=path.join(options.pmRoot,"runtime","workspace-memory.json"),warnings=[],persisted=await readPersistedWorkspaceMemory(filePath),parsed=persisted.snapshot;if(persisted.invalid&&warnings.push("workspace_memory_invalid"),parsed?.source_cursor===sourceCursor&&parsed.source_item_count===items.length)return{snapshot:parsed,cache_status:"fresh",warnings};parsed&&warnings.push("workspace_memory_stale");const snapshot=buildWorkspaceMemorySnapshot(items,{statusRegistry:options.statusRegistry,sourceCursor,now:options.now});try{await writeFileAtomic(filePath,`${JSON.stringify(snapshot)}
2
+ `)}catch{warnings.push("workspace_memory_write_failed")}return{snapshot,cache_status:"rebuilt",warnings}}function selectWorkspaceMemoryRollups(snapshot,tokenBudget,limit=DEFAULT_ROLLUP_LIMIT){const boundedBudget=Math.max(0,Math.floor(tokenBudget));let consumed=0;const selected=[];for(const rollup of snapshot.rollups){if(selected.length>=Math.max(0,Math.floor(limit)))break;const tokens=Math.ceil(JSON.stringify(rollup).length/4);consumed+tokens>boundedBudget||(selected.push(rollup),consumed+=tokens)}return selected}function selectWorkspaceMemory(memory,tokenBudget,limit=DEFAULT_ROLLUP_LIMIT){if(memory.snapshot===null)return;const rollups=selectWorkspaceMemoryRollups(memory.snapshot,tokenBudget,limit);if(rollups.length!==0)return{cache_status:memory.cache_status==="fresh"?"fresh":"rebuilt",source_cursor:memory.snapshot.source_cursor,...memory.snapshot.completion_time_sources?{completion_time_sources:{...memory.snapshot.completion_time_sources}}:{},rollups}}function searchWorkspaceMemory(snapshot,query,limit=5){if(snapshot===null)return[];const tokens=query.trim().toLowerCase().split(/\s+/u).filter(Boolean);return tokens.length===0?[]:snapshot.rollups.map(rollup=>({rollup,score:tokens.filter(token=>[rollup.key,rollup.label,...rollup.outcomes,...rollup.representative_items.flatMap(item=>[item.id,item.title])].join(" ").toLowerCase().includes(token)).length})).filter(({score})=>score>0).sort((left,right)=>right.score-left.score||right.rollup.last_closed_at.localeCompare(left.rollup.last_closed_at)||left.rollup.key.localeCompare(right.rollup.key)).slice(0,Math.max(0,Math.floor(limit))).map(({rollup})=>rollup)}function searchWorkspaceMemoryReadResult(memory,query,limit=5){const matches=searchWorkspaceMemory(memory.snapshot,query,limit);if(matches.length!==0)return{cache_status:memory.cache_status==="fresh"?"fresh":"rebuilt",matches}}export{DEFAULT_WORKSPACE_MEMORY_MINIMUM_ITEMS,buildWorkspaceMemorySnapshot,readWorkspaceMemory,searchWorkspaceMemory,searchWorkspaceMemoryReadResult,selectWorkspaceMemory,selectWorkspaceMemoryRollups};
3
3
  //# sourceMappingURL=workspace-memory.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]="76fdc288-42b3-52b9-adc7-81e504f23ae3")}catch(e2){}})();import{runWithReproducibleExecution,validateReproducibleExecutionSettings}from"../core/reproducibility/context.js";const PM_WORKSPACE_RECIPE_SCHEMA="https://schema.unbrained.dev/pm/workspace-recipe/v1";function cloneAndFreezeRecipeJson(value,location){if(value===null||typeof value==="boolean"||typeof value==="string"){return value}if(typeof value==="number"){if(!Number.isFinite(value)){throw new Error(`Workspace recipe JSON number must be finite at ${location}`)}return value}if(Array.isArray(value)){return Object.freeze(value.map((entry,index)=>cloneAndFreezeRecipeJson(entry,`${location}[${index}]`)))}if(typeof value!=="object"||Object.getPrototypeOf(value)!==Object.prototype&&Object.getPrototypeOf(value)!==null){throw new Error(`Workspace recipe input must contain JSON values at ${location}`)}return Object.freeze(Object.fromEntries(Object.entries(value).map(([key,entry])=>[key,cloneAndFreezeRecipeJson(entry,`${location}.${key}`)])))}function defineWorkspaceRecipe(recipe){if(recipe.schema!==PM_WORKSPACE_RECIPE_SCHEMA){throw new Error(`Unsupported workspace recipe schema: ${recipe.schema}`)}const normalized=validateReproducibleExecutionSettings(recipe);if(recipe.operations.some(operation=>operation.action.trim().length===0||operation.input===null||Array.isArray(operation.input))){throw new Error("Workspace recipe operations require an action and object input")}return Object.freeze({...normalized,operations:Object.freeze(recipe.operations.map((operation,index)=>Object.freeze({action:operation.action,input:cloneAndFreezeRecipeJson(operation.input,`operations[${index}].input`)})))})}async function runWithWorkspaceRecipe(recipe,operation){const defined=defineWorkspaceRecipe(recipe);return runWithReproducibleExecution(defined,operation)}async function executeWorkspaceRecipe(recipe,execute){return runWithWorkspaceRecipe(recipe,async()=>{const results=[];for(const[index,operation]of recipe.operations.entries()){results.push(await execute(operation,index))}return results})}export{PM_WORKSPACE_RECIPE_SCHEMA,defineWorkspaceRecipe,executeWorkspaceRecipe,runWithWorkspaceRecipe};
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]="2b24276b-948b-50bd-bfd9-f429cd74be70")}catch{}})();import{runWithReproducibleExecution,validateReproducibleExecutionSettings}from"../core/reproducibility/context.js";const PM_WORKSPACE_RECIPE_SCHEMA="https://schema.unbrained.dev/pm/workspace-recipe/v1";function cloneAndFreezeRecipeJson(value,location){if(value===null||typeof value=="boolean"||typeof value=="string")return value;if(typeof value=="number"){if(!Number.isFinite(value))throw new Error(`Workspace recipe JSON number must be finite at ${location}`);return value}if(Array.isArray(value))return Object.freeze(value.map((entry,index)=>cloneAndFreezeRecipeJson(entry,`${location}[${index}]`)));if(typeof value!="object"||Object.getPrototypeOf(value)!==Object.prototype&&Object.getPrototypeOf(value)!==null)throw new Error(`Workspace recipe input must contain JSON values at ${location}`);return Object.freeze(Object.fromEntries(Object.entries(value).map(([key,entry])=>[key,cloneAndFreezeRecipeJson(entry,`${location}.${key}`)])))}function defineWorkspaceRecipe(recipe){if(recipe.schema!==PM_WORKSPACE_RECIPE_SCHEMA)throw new Error(`Unsupported workspace recipe schema: ${recipe.schema}`);const normalized=validateReproducibleExecutionSettings(recipe);if(recipe.operations.some(operation=>operation.action.trim().length===0||operation.input===null||Array.isArray(operation.input)))throw new Error("Workspace recipe operations require an action and object input");return Object.freeze({...normalized,operations:Object.freeze(recipe.operations.map((operation,index)=>Object.freeze({action:operation.action,input:cloneAndFreezeRecipeJson(operation.input,`operations[${index}].input`)})))})}async function runWithWorkspaceRecipe(recipe,operation){const defined=defineWorkspaceRecipe(recipe);return runWithReproducibleExecution(defined,operation)}async function executeWorkspaceRecipe(recipe,execute){return runWithWorkspaceRecipe(recipe,async()=>{const results=[];for(const[index,operation]of recipe.operations.entries())results.push(await execute(operation,index));return results})}export{PM_WORKSPACE_RECIPE_SCHEMA,defineWorkspaceRecipe,executeWorkspaceRecipe,runWithWorkspaceRecipe};
2
2
  //# sourceMappingURL=workspace-recipe.js.map
@@ -1,5 +1,6 @@
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]="91604cb2-8afd-585e-9c18-26e223df25bc")}catch(e2){}})();import crypto from"node:crypto";import{cp,lstat,mkdir,readFile,readdir,rename,rm,writeFile}from"node:fs/promises";import path from"node:path";import{isFileMissingError,writeFileAtomic}from"../core/fs/fs-utils.js";import{appendWorkspaceAuditEvent}from"../core/history/workspace-history.js";import{acquireLock}from"../core/lock/lock.js";import{getLockPath}from"../core/store/paths.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{withHostEnvironmentBoundary}from"./environment/host-environment-errors.js";const SNAPSHOT_SCHEMA="https://schema.unbrained.dev/pm/workspace-snapshot/v1";const WORKSPACE_SNAPSHOT_ACTIONS=["create","list","inspect","restore","delete"];const SNAPSHOT_RUNTIME_PATH=path.join("runtime","workspace-snapshots");const EXCLUDED_ROOT_NAMES=new Set(["checkpoints","locks","runtime","search","transactions"]);const SNAPSHOT_TARGET_PATTERN=/^[a-z0-9][a-z0-9._-]*$/;const WORKSPACE_WRITER_LOCK_ID="sdk-workspace-transaction";const SNAPSHOT_HOST_FAULT_CODES={capacity:{code:"workspace_snapshot_storage_exhausted"},permission:{code:"workspace_snapshot_permission_denied"},resource:{code:"workspace_snapshot_resource_exhausted"}};const DEFAULT_ATOMIC_OPERATIONS={renameEntry:rename,removeEntry:async target=>{await rm(target,{recursive:true,force:true})}};class WorkspaceLockHeartbeat{lockPath;owner;intervalMs;timer;refresh;failure;constructor(lockPath,owner,ttlSeconds){this.lockPath=lockPath;this.owner=owner;this.intervalMs=Math.max(10,Math.floor(ttlSeconds*1e3/3))}start(){this.scheduleRenewal();this.timer=setInterval(()=>{this.scheduleRenewal()},this.intervalMs);this.timer.unref()}async refreshNow(){this.scheduleRenewal();await this.refresh;this.assertHealthy()}assertHealthy(){if(this.failure!==void 0){throw new Error("Workspace snapshot restore lost its writer lock",{cause:this.failure})}}async stop(){if(this.timer!==void 0)clearInterval(this.timer);await this.refresh;this.assertHealthy()}scheduleRenewal(){if(this.refresh!==void 0||this.failure!==void 0)return;this.refresh=this.renew().catch(error=>{this.failure=error}).finally(()=>{this.refresh=void 0})}async renew(){const parsed=JSON.parse(await readFile(this.lockPath,"utf8"));if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){throw new Error("Workspace writer lock has invalid structure")}const lock=parsed;if(lock.id!==WORKSPACE_WRITER_LOCK_ID||lock.owner!==this.owner||lock.pid!==process.pid){throw new Error("Workspace writer lock ownership changed")}await writeFileAtomic(this.lockPath,`${JSON.stringify({...lock,created_at:new Date().toISOString()},null,2)}
2
- `)}}const _testOnlyWorkspaceSnapshot={WorkspaceLockHeartbeat,withSnapshotFilesystemGuard};async function collectAuthoritativeFiles(root,relative=""){const entries=await readdir(path.join(root,relative),{withFileTypes:true});const files=[];for(const entry of entries.sort((left,right)=>left.name.localeCompare(right.name))){if(relative.length===0&&EXCLUDED_ROOT_NAMES.has(entry.name)){continue}const entryRelative=path.posix.join(relative.replaceAll(path.sep,"/"),entry.name);if(entry.isSymbolicLink()){throw new Error(`Workspace snapshots reject symbolic links: ${entryRelative}`)}if(entry.isDirectory()){files.push(...await collectAuthoritativeFiles(root,entryRelative))}else if(entry.isFile()){files.push(entryRelative)}else{throw new Error(`Workspace snapshots reject unsupported filesystem entries: ${entryRelative}`)}}return files}async function buildManifest(pmRoot){const files=await collectAuthoritativeFiles(pmRoot);const hash=crypto.createHash("sha256");const contents=[];let bytes=0;for(const file of files){const content=await readFile(path.join(pmRoot,file));contents.push(content);bytes+=content.byteLength;hash.update(file);hash.update("\0");hash.update(String(content.byteLength));hash.update("\0");hash.update(content)}const fingerprint=hash.digest("hex");return{manifest:{schema:SNAPSHOT_SCHEMA,fingerprint,files,bytes},contents}}function lineCount(content){if(content===void 0||content.byteLength===0){return 0}return content.toString("utf8").split("\n").filter(line=>line.trim().length>0).length}async function snapshotContents(root,files){const contents=new Map;for(let offset=0;offset<files.length;offset+=32){const batch=files.slice(offset,offset+32);const entries=await Promise.all(batch.map(async file=>[file,await readFile(path.join(root,file))]));for(const[file,content]of entries)contents.set(file,content)}return contents}function validateSnapshotTarget(target){if(!SNAPSHOT_TARGET_PATTERN.test(target)){throw new PmCliError("Snapshot names and fingerprints must use lowercase letters, digits, dots, underscores, or hyphens",EXIT_CODE.USAGE,{code:"invalid_workspace_snapshot_target",required:"Provide a non-empty lowercase snapshot name or 64-character hexadecimal fingerprint.",why:"Snapshot targets are used as portable reference filenames and content identities.",examples:["pm workspace snapshot list --json","pm workspace snapshot inspect baseline --json"],nextSteps:["List available snapshots, then retry with a returned name or fingerprint."],recovery:{suggested_retry:"pm workspace snapshot list --json"}})}}async function withSnapshotFilesystemGuard(operation,run){return withHostEnvironmentBoundary(`workspace_snapshot_${operation}`,run,{codes:{capacity:SNAPSHOT_HOST_FAULT_CODES.capacity.code,permission:SNAPSHOT_HOST_FAULT_CODES.permission.code,resource:SNAPSHOT_HOST_FAULT_CODES.resource.code},why:"Snapshot create and restore copy authoritative tracker state before activation, so the stage needs capacity and write access up front.",nextSteps:["Reclaim rebuildable tracker cache space with pm gc, then retry."],suggestedRetry:"pm gc --json"})}function snapshotStore(pmRoot){return path.join(pmRoot,SNAPSHOT_RUNTIME_PATH)}function workspaceSnapshotNotFound(target){return new PmCliError(`Unknown workspace snapshot: ${target}`,EXIT_CODE.NOT_FOUND,{code:"workspace_snapshot_not_found",required:"Use a snapshot name or fingerprint returned by snapshot list.",why:"The requested reference or immutable snapshot object does not exist.",examples:["pm workspace snapshot list --json"],nextSteps:["List available snapshots and retry with an exact target."],recovery:{suggested_retry:"pm workspace snapshot list --json"}})}async function readSnapshotJson(file,target){try{return JSON.parse(await readFile(file,"utf8"))}catch(error){if(isFileMissingError(error)){throw workspaceSnapshotNotFound(target)}throw error}}async function removeSnapshotEntry(entry,target,recursive){try{await rm(entry,{recursive})}catch(error){if(isFileMissingError(error)){throw workspaceSnapshotNotFound(target)}throw error}}async function publishWorkspaceSnapshotObject(temporaryRoot,objectRoot,operations=DEFAULT_ATOMIC_OPERATIONS){try{await operations.renameEntry(temporaryRoot,objectRoot);return false}catch(error){if(!(error instanceof Error&&"code"in error&&(error.code==="EEXIST"||error.code==="ENOTEMPTY"))){throw error}await operations.removeEntry(temporaryRoot);return true}}async function swapWorkspaceSnapshotRootWithActivation(staging,pmRoot,backup,operations,afterActivation){await operations.renameEntry(pmRoot,backup);try{await operations.renameEntry(staging,pmRoot);await afterActivation?.()}catch(error){await operations.renameEntry(backup,pmRoot);await operations.removeEntry(staging);throw error}await operations.removeEntry(backup)}async function swapWorkspaceSnapshotRoot(staging,pmRoot,backup,operations=DEFAULT_ATOMIC_OPERATIONS){await swapWorkspaceSnapshotRootWithActivation(staging,pmRoot,backup,operations)}async function resolveSnapshotFingerprint(pmRoot,target){validateSnapshotTarget(target);if(/^[a-f0-9]{64}$/.test(target)){return target}const reference=await readSnapshotJson(path.join(snapshotStore(pmRoot),"refs",`${target}.json`),target);return reference.fingerprint}async function createWorkspaceSnapshot(pmRoot,options={}){if(options.name!==void 0){validateSnapshotTarget(options.name);if(/^[a-f0-9]{64}$/.test(options.name)){throw new PmCliError("Snapshot names must not be 64-character lowercase hexadecimal fingerprints",EXIT_CODE.USAGE,{code:"workspace_snapshot_name_reserved_fingerprint",required:"Choose a human-readable reference name that cannot be mistaken for a content fingerprint.",why:"Exact 64-character hexadecimal values address immutable objects.",examples:["pm workspace snapshot create baseline --json"],nextSteps:["Retry with a shorter descriptive snapshot name."]})}}const{manifest,contents}=await buildManifest(pmRoot);const store=snapshotStore(pmRoot);const objectRoot=path.join(store,"objects",manifest.fingerprint);let deduplicated=false;try{const objectStat=await lstat(objectRoot);deduplicated=objectStat.isDirectory()}catch(error){if(!(error instanceof Error&&"code"in error&&isFileMissingError(error))){throw error}}if(!deduplicated){const temporaryRoot=path.join(store,"objects",`.create-${process.pid}-${crypto.randomUUID()}`);await withSnapshotFilesystemGuard("create_object",async()=>{await mkdir(path.join(temporaryRoot,"files"),{recursive:true});for(const[index,file]of manifest.files.entries()){const target=path.join(temporaryRoot,"files",file);await mkdir(path.dirname(target),{recursive:true});await writeFile(target,contents[index])}await writeFile(path.join(temporaryRoot,"manifest.json"),`${JSON.stringify(manifest,null,2)}
3
- `,"utf8");await mkdir(path.dirname(objectRoot),{recursive:true})});deduplicated=await publishWorkspaceSnapshotObject(temporaryRoot,objectRoot)}if(options.name!==void 0){const reference={name:options.name,fingerprint:manifest.fingerprint};const refsRoot=path.join(store,"refs");await mkdir(refsRoot,{recursive:true});const temporaryRef=path.join(refsRoot,`.ref-${process.pid}-${crypto.randomUUID()}`);await writeFile(temporaryRef,`${JSON.stringify(reference,null,2)}
4
- `,"utf8");await rename(temporaryRef,path.join(refsRoot,`${options.name}.json`))}return{manifest,...options.name===void 0?{}:{name:options.name},deduplicated}}async function inspectWorkspaceSnapshot(pmRoot,target){const fingerprint=await resolveSnapshotFingerprint(pmRoot,target);const manifest=await readSnapshotJson(path.join(snapshotStore(pmRoot),"objects",fingerprint,"manifest.json"),target);if(manifest.schema!==SNAPSHOT_SCHEMA||manifest.fingerprint!==fingerprint){throw new PmCliError(`Snapshot manifest identity mismatch: ${target}`,EXIT_CODE.CONFLICT,{code:"workspace_snapshot_manifest_mismatch",required:"Use an intact snapshot whose manifest fingerprint matches its object path.",why:"Content identity must be verified before snapshot data is trusted.",examples:["pm workspace snapshot list --json"],nextSteps:["Inspect or recreate the snapshot before restoring it."]})}return manifest}async function listWorkspaceSnapshots(pmRoot){const store=snapshotStore(pmRoot);const objectNames=await readdir(path.join(store,"objects")).catch(error=>{if(error instanceof Error&&"code"in error&&isFileMissingError(error)){return[]}throw error});const referenceNames=await readdir(path.join(store,"refs")).catch(error=>{if(error instanceof Error&&"code"in error&&isFileMissingError(error)){return[]}throw error});return{objects:await Promise.all(objectNames.filter(name=>/^[a-f0-9]{64}$/.test(name)).sort().map(name=>inspectWorkspaceSnapshot(pmRoot,name))),references:await Promise.all(referenceNames.filter(name=>name.endsWith(".json")).sort().map(async name=>JSON.parse(await readFile(path.join(store,"refs",name),"utf8"))))}}async function planWorkspaceSnapshotRestore(pmRoot,target){const targetManifest=await inspectWorkspaceSnapshot(pmRoot,target);const{manifest:currentManifest,contents:currentContentList}=await buildManifest(pmRoot);const currentContents=new Map(currentManifest.files.map((file,index)=>[file,currentContentList[index]]));const targetContents=await snapshotContents(path.join(snapshotStore(pmRoot),"objects",targetManifest.fingerprint,"files"),targetManifest.files);const currentFiles=new Set(currentManifest.files);const targetFiles=new Set(targetManifest.files);const changedFiles=new Set([...currentFiles,...targetFiles]);for(const file of changedFiles){const currentContent=currentContents.get(file);const targetContent=targetContents.get(file);if(currentContent!==void 0&&targetContent!==void 0&&currentContent.equals(targetContent)){changedFiles.delete(file)}}const affectedHistoryStreams=currentManifest.files.filter(file=>file.startsWith("history/")&&file.endsWith(".jsonl")).map(file=>{const currentEntries=lineCount(currentContents.get(file));const targetEntries=lineCount(targetContents.get(file));return{path:file,current_entries:currentEntries,target_entries:targetEntries,removed_entries:Math.max(0,currentEntries-targetEntries)}}).filter(entry=>entry.removed_entries>0).sort((left,right)=>left.path.localeCompare(right.path));return{target_fingerprint:targetManifest.fingerprint,current_fingerprint:currentManifest.fingerprint,changed_file_count:changedFiles.size,removed_file_count:[...currentFiles].filter(file=>!targetFiles.has(file)).length,added_file_count:[...targetFiles].filter(file=>!currentFiles.has(file)).length,removed_item_count:[...currentFiles].filter(file=>file.endsWith(".toon")&&!targetFiles.has(file)).length,affected_history_stream_count:affectedHistoryStreams.length,removed_history_entry_count:affectedHistoryStreams.reduce((total,entry)=>total+entry.removed_entries,0),affected_history_streams:affectedHistoryStreams,changes_authoritative_state:currentManifest.fingerprint!==targetManifest.fingerprint}}async function restoreWorkspaceSnapshotWithRecovery(pmRoot,target,options={}){if(options.force!==true){throw new PmCliError("Workspace snapshot restore requires explicit force confirmation; inspect the impact with planWorkspaceSnapshotRestore or pm workspace snapshot restore <target> --dry-run, then retry with force",EXIT_CODE.USAGE,{code:"workspace_snapshot_force_required",required:"Preview the destructive impact, then explicitly confirm the restore.",why:"A restore replaces the complete authoritative tracker state.",examples:[`pm workspace snapshot restore ${target} --dry-run --json`,`pm workspace snapshot restore ${target} --force --json`],nextSteps:["Review the dry-run counts before retrying with --force."],recovery:{suggested_retry:`pm workspace snapshot restore ${target} --dry-run --json`}})}const author=options.author?.trim()||"pm-sdk";const lockTtlSeconds=options.lockTtlSeconds??60;const lockWaitMs=options.lockWaitMs??5e3;const releaseWorkspaceLock=await acquireLock(pmRoot,WORKSPACE_WRITER_LOCK_ID,lockTtlSeconds,author,false,false,lockWaitMs);const heartbeat=new WorkspaceLockHeartbeat(getLockPath(pmRoot,WORKSPACE_WRITER_LOCK_ID),author,lockTtlSeconds);heartbeat.start();await heartbeat.refreshNow();let staging;let swapStarted=false;let heartbeatStopped=false;try{const plan=await planWorkspaceSnapshotRestore(pmRoot,target);const manifest=await inspectWorkspaceSnapshot(pmRoot,target);const recovery=await createWorkspaceSnapshot(pmRoot);const fingerprint=manifest.fingerprint;const store=snapshotStore(pmRoot);const source=path.join(store,"objects",fingerprint,"files");const parent=path.dirname(pmRoot);const base=path.basename(pmRoot);staging=path.join(parent,`.${base}.restore-${crypto.randomUUID()}`);const backup=path.join(parent,`.${base}.backup-${crypto.randomUUID()}`);await withSnapshotFilesystemGuard("restore_stage",async()=>{await mkdir(staging,{recursive:true});await cp(source,staging,{recursive:true,force:false});await mkdir(path.join(staging,"runtime"),{recursive:true});await cp(store,path.join(staging,SNAPSHOT_RUNTIME_PATH),{recursive:true,force:false})});const audit=await appendWorkspaceAuditEvent({pmRoot:staging,op:"workspace_snapshot_restore",author,message:options.message??`Restore workspace snapshot ${fingerprint}; recovery snapshot ${recovery.manifest.fingerprint}`,context:{target_fingerprint:fingerprint,pre_restore_fingerprint:recovery.manifest.fingerprint,changed_file_count:plan.changed_file_count,removed_file_count:plan.removed_file_count,removed_item_count:plan.removed_item_count,affected_history_stream_count:plan.affected_history_stream_count,removed_history_entry_count:plan.removed_history_entry_count},lockTtlSeconds,lockWaitMs});const auditHistoryPath=path.relative(staging,audit.historyPath).replaceAll("\\","/");await heartbeat.stop();heartbeatStopped=true;const stagedWorkspaceLock=getLockPath(staging,WORKSPACE_WRITER_LOCK_ID);await mkdir(path.dirname(stagedWorkspaceLock),{recursive:true});await writeFile(stagedWorkspaceLock,await readFile(getLockPath(pmRoot,WORKSPACE_WRITER_LOCK_ID)),{flag:"wx"});swapStarted=true;await swapWorkspaceSnapshotRootWithActivation(staging,pmRoot,backup,DEFAULT_ATOMIC_OPERATIONS,async()=>{heartbeat.start();heartbeatStopped=false;await heartbeat.refreshNow()});await heartbeat.stop();heartbeatStopped=true;return{manifest,plan,recovery_fingerprint:recovery.manifest.fingerprint,audit_history_path:auditHistoryPath,audit_operation:"workspace_snapshot_restore"}}catch(error){if(staging!==void 0&&!swapStarted){await Promise.allSettled([rm(staging,{recursive:true,force:true})])}throw error}finally{try{if(!heartbeatStopped)await heartbeat.stop()}catch{}finally{await releaseWorkspaceLock()}}}async function restoreWorkspaceSnapshot(pmRoot,target){return(await restoreWorkspaceSnapshotWithRecovery(pmRoot,target,{force:true,message:"Restore requested through the compatibility SDK signature"})).manifest}async function deleteWorkspaceSnapshot(pmRoot,target){validateSnapshotTarget(target);const store=snapshotStore(pmRoot);if(!/^[a-f0-9]{64}$/.test(target)){await removeSnapshotEntry(path.join(store,"refs",`${target}.json`),target,false);return{deleted:"reference",target}}const{references}=await listWorkspaceSnapshots(pmRoot);if(references.some(reference=>reference.fingerprint===target)){throw new Error(`Snapshot object ${target} is still referenced`)}await removeSnapshotEntry(path.join(store,"objects",target),target,true);return{deleted:"object",target}}export{SNAPSHOT_SCHEMA,WORKSPACE_SNAPSHOT_ACTIONS,_testOnlyWorkspaceSnapshot,createWorkspaceSnapshot,deleteWorkspaceSnapshot,inspectWorkspaceSnapshot,listWorkspaceSnapshots,planWorkspaceSnapshotRestore,publishWorkspaceSnapshotObject,restoreWorkspaceSnapshot,restoreWorkspaceSnapshotWithRecovery,swapWorkspaceSnapshotRoot};
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]="3b4a5521-a665-5f60-8d01-16033b078916")}catch{}})();import crypto from"node:crypto";import{cp,lstat,mkdir,readFile,readdir,rename,rm,writeFile}from"node:fs/promises";import path from"node:path";import{isFileMissingError,writeFileAtomic}from"../core/fs/fs-utils.js";import{appendWorkspaceAuditEvent}from"../core/history/workspace-history.js";import{acquireLock}from"../core/lock/lock.js";import{getLockPath}from"../core/store/paths.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{withHostEnvironmentBoundary}from"./environment/host-environment-errors.js";const SNAPSHOT_SCHEMA="https://schema.unbrained.dev/pm/workspace-snapshot/v1",WORKSPACE_SNAPSHOT_ACTIONS=["create","list","inspect","restore","delete"],SNAPSHOT_RUNTIME_PATH=path.join("runtime","workspace-snapshots"),EXCLUDED_ROOT_NAMES=new Set(["checkpoints","locks","runtime","search","transactions"]),SNAPSHOT_TARGET_PATTERN=/^[a-z0-9][a-z0-9._-]*$/,WORKSPACE_WRITER_LOCK_ID="sdk-workspace-transaction",SNAPSHOT_HOST_FAULT_CODES={capacity:{code:"workspace_snapshot_storage_exhausted"},permission:{code:"workspace_snapshot_permission_denied"},resource:{code:"workspace_snapshot_resource_exhausted"}},DEFAULT_ATOMIC_OPERATIONS={renameEntry:rename,removeEntry:async target=>{await rm(target,{recursive:!0,force:!0})}};class WorkspaceLockHeartbeat{lockPath;owner;intervalMs;timer;refresh;failure;constructor(lockPath,owner,ttlSeconds){this.lockPath=lockPath,this.owner=owner,this.intervalMs=Math.max(10,Math.floor(ttlSeconds*1e3/3))}start(){this.scheduleRenewal(),this.timer=setInterval(()=>{this.scheduleRenewal()},this.intervalMs),this.timer.unref()}async refreshNow(){this.scheduleRenewal(),await this.refresh,this.assertHealthy()}assertHealthy(){if(this.failure!==void 0)throw new Error("Workspace snapshot restore lost its writer lock",{cause:this.failure})}async stop(){this.timer!==void 0&&clearInterval(this.timer),await this.refresh,this.assertHealthy()}scheduleRenewal(){this.refresh!==void 0||this.failure!==void 0||(this.refresh=this.renew().catch(error=>{this.failure=error}).finally(()=>{this.refresh=void 0}))}async renew(){const parsed=JSON.parse(await readFile(this.lockPath,"utf8"));if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new Error("Workspace writer lock has invalid structure");const lock=parsed;if(lock.id!==WORKSPACE_WRITER_LOCK_ID||lock.owner!==this.owner||lock.pid!==process.pid)throw new Error("Workspace writer lock ownership changed");await writeFileAtomic(this.lockPath,`${JSON.stringify({...lock,created_at:new Date().toISOString()},null,2)}
2
+ `)}}const _testOnlyWorkspaceSnapshot={WorkspaceLockHeartbeat,withSnapshotFilesystemGuard};async function collectAuthoritativeFiles(root,relative=""){const entries=await readdir(path.join(root,relative),{withFileTypes:!0}),files=[];for(const entry of entries.sort((left,right)=>left.name.localeCompare(right.name))){if(relative.length===0&&EXCLUDED_ROOT_NAMES.has(entry.name))continue;const entryRelative=path.posix.join(relative.replaceAll(path.sep,"/"),entry.name);if(entry.isSymbolicLink())throw new Error(`Workspace snapshots reject symbolic links: ${entryRelative}`);if(entry.isDirectory())files.push(...await collectAuthoritativeFiles(root,entryRelative));else if(entry.isFile())files.push(entryRelative);else throw new Error(`Workspace snapshots reject unsupported filesystem entries: ${entryRelative}`)}return files}async function buildManifest(pmRoot){const files=await collectAuthoritativeFiles(pmRoot),hash=crypto.createHash("sha256"),contents=[];let bytes=0;for(const file of files){const content=await readFile(path.join(pmRoot,file));contents.push(content),bytes+=content.byteLength,hash.update(file),hash.update("\0"),hash.update(String(content.byteLength)),hash.update("\0"),hash.update(content)}const fingerprint=hash.digest("hex");return{manifest:{schema:SNAPSHOT_SCHEMA,fingerprint,files,bytes},contents}}function lineCount(content){return content===void 0||content.byteLength===0?0:content.toString("utf8").split(`
3
+ `).filter(line=>line.trim().length>0).length}async function snapshotContents(root,files){const contents=new Map;for(let offset=0;offset<files.length;offset+=32){const batch=files.slice(offset,offset+32),entries=await Promise.all(batch.map(async file=>[file,await readFile(path.join(root,file))]));for(const[file,content]of entries)contents.set(file,content)}return contents}function validateSnapshotTarget(target){if(!SNAPSHOT_TARGET_PATTERN.test(target))throw new PmCliError("Snapshot names and fingerprints must use lowercase letters, digits, dots, underscores, or hyphens",EXIT_CODE.USAGE,{code:"invalid_workspace_snapshot_target",required:"Provide a non-empty lowercase snapshot name or 64-character hexadecimal fingerprint.",why:"Snapshot targets are used as portable reference filenames and content identities.",examples:["pm workspace snapshot list --json","pm workspace snapshot inspect baseline --json"],nextSteps:["List available snapshots, then retry with a returned name or fingerprint."],recovery:{suggested_retry:"pm workspace snapshot list --json"}})}async function withSnapshotFilesystemGuard(operation,run){return withHostEnvironmentBoundary(`workspace_snapshot_${operation}`,run,{codes:{capacity:SNAPSHOT_HOST_FAULT_CODES.capacity.code,permission:SNAPSHOT_HOST_FAULT_CODES.permission.code,resource:SNAPSHOT_HOST_FAULT_CODES.resource.code},why:"Snapshot create and restore copy authoritative tracker state before activation, so the stage needs capacity and write access up front.",nextSteps:["Reclaim rebuildable tracker cache space with pm gc, then retry."],suggestedRetry:"pm gc --json"})}function snapshotStore(pmRoot){return path.join(pmRoot,SNAPSHOT_RUNTIME_PATH)}function workspaceSnapshotNotFound(target){return new PmCliError(`Unknown workspace snapshot: ${target}`,EXIT_CODE.NOT_FOUND,{code:"workspace_snapshot_not_found",required:"Use a snapshot name or fingerprint returned by snapshot list.",why:"The requested reference or immutable snapshot object does not exist.",examples:["pm workspace snapshot list --json"],nextSteps:["List available snapshots and retry with an exact target."],recovery:{suggested_retry:"pm workspace snapshot list --json"}})}async function readSnapshotJson(file,target){try{return JSON.parse(await readFile(file,"utf8"))}catch(error){throw isFileMissingError(error)?workspaceSnapshotNotFound(target):error}}async function removeSnapshotEntry(entry,target,recursive){try{await rm(entry,{recursive})}catch(error){throw isFileMissingError(error)?workspaceSnapshotNotFound(target):error}}async function publishWorkspaceSnapshotObject(temporaryRoot,objectRoot,operations=DEFAULT_ATOMIC_OPERATIONS){try{return await operations.renameEntry(temporaryRoot,objectRoot),!1}catch(error){if(!(error instanceof Error&&"code"in error&&(error.code==="EEXIST"||error.code==="ENOTEMPTY")))throw error;return await operations.removeEntry(temporaryRoot),!0}}async function swapWorkspaceSnapshotRootWithActivation(staging,pmRoot,backup,operations,afterActivation){await operations.renameEntry(pmRoot,backup);try{await operations.renameEntry(staging,pmRoot),await afterActivation?.()}catch(error){throw await operations.renameEntry(backup,pmRoot),await operations.removeEntry(staging),error}await operations.removeEntry(backup)}async function swapWorkspaceSnapshotRoot(staging,pmRoot,backup,operations=DEFAULT_ATOMIC_OPERATIONS){await swapWorkspaceSnapshotRootWithActivation(staging,pmRoot,backup,operations)}async function resolveSnapshotFingerprint(pmRoot,target){return validateSnapshotTarget(target),/^[a-f0-9]{64}$/.test(target)?target:(await readSnapshotJson(path.join(snapshotStore(pmRoot),"refs",`${target}.json`),target)).fingerprint}async function createWorkspaceSnapshot(pmRoot,options={}){if(options.name!==void 0&&(validateSnapshotTarget(options.name),/^[a-f0-9]{64}$/.test(options.name)))throw new PmCliError("Snapshot names must not be 64-character lowercase hexadecimal fingerprints",EXIT_CODE.USAGE,{code:"workspace_snapshot_name_reserved_fingerprint",required:"Choose a human-readable reference name that cannot be mistaken for a content fingerprint.",why:"Exact 64-character hexadecimal values address immutable objects.",examples:["pm workspace snapshot create baseline --json"],nextSteps:["Retry with a shorter descriptive snapshot name."]});const{manifest,contents}=await buildManifest(pmRoot),store=snapshotStore(pmRoot),objectRoot=path.join(store,"objects",manifest.fingerprint);let deduplicated=!1;try{deduplicated=(await lstat(objectRoot)).isDirectory()}catch(error){if(!(error instanceof Error&&"code"in error&&isFileMissingError(error)))throw error}if(!deduplicated){const temporaryRoot=path.join(store,"objects",`.create-${process.pid}-${crypto.randomUUID()}`);await withSnapshotFilesystemGuard("create_object",async()=>{await mkdir(path.join(temporaryRoot,"files"),{recursive:!0});for(const[index,file]of manifest.files.entries()){const target=path.join(temporaryRoot,"files",file);await mkdir(path.dirname(target),{recursive:!0}),await writeFile(target,contents[index])}await writeFile(path.join(temporaryRoot,"manifest.json"),`${JSON.stringify(manifest,null,2)}
4
+ `,"utf8"),await mkdir(path.dirname(objectRoot),{recursive:!0})}),deduplicated=await publishWorkspaceSnapshotObject(temporaryRoot,objectRoot)}if(options.name!==void 0){const reference={name:options.name,fingerprint:manifest.fingerprint},refsRoot=path.join(store,"refs");await mkdir(refsRoot,{recursive:!0});const temporaryRef=path.join(refsRoot,`.ref-${process.pid}-${crypto.randomUUID()}`);await writeFile(temporaryRef,`${JSON.stringify(reference,null,2)}
5
+ `,"utf8"),await rename(temporaryRef,path.join(refsRoot,`${options.name}.json`))}return{manifest,...options.name===void 0?{}:{name:options.name},deduplicated}}async function inspectWorkspaceSnapshot(pmRoot,target){const fingerprint=await resolveSnapshotFingerprint(pmRoot,target),manifest=await readSnapshotJson(path.join(snapshotStore(pmRoot),"objects",fingerprint,"manifest.json"),target);if(manifest.schema!==SNAPSHOT_SCHEMA||manifest.fingerprint!==fingerprint)throw new PmCliError(`Snapshot manifest identity mismatch: ${target}`,EXIT_CODE.CONFLICT,{code:"workspace_snapshot_manifest_mismatch",required:"Use an intact snapshot whose manifest fingerprint matches its object path.",why:"Content identity must be verified before snapshot data is trusted.",examples:["pm workspace snapshot list --json"],nextSteps:["Inspect or recreate the snapshot before restoring it."]});return manifest}async function listWorkspaceSnapshots(pmRoot){const store=snapshotStore(pmRoot),objectNames=await readdir(path.join(store,"objects")).catch(error=>{if(error instanceof Error&&"code"in error&&isFileMissingError(error))return[];throw error}),referenceNames=await readdir(path.join(store,"refs")).catch(error=>{if(error instanceof Error&&"code"in error&&isFileMissingError(error))return[];throw error});return{objects:await Promise.all(objectNames.filter(name=>/^[a-f0-9]{64}$/.test(name)).sort().map(name=>inspectWorkspaceSnapshot(pmRoot,name))),references:await Promise.all(referenceNames.filter(name=>name.endsWith(".json")).sort().map(async name=>JSON.parse(await readFile(path.join(store,"refs",name),"utf8"))))}}async function planWorkspaceSnapshotRestore(pmRoot,target){const targetManifest=await inspectWorkspaceSnapshot(pmRoot,target),{manifest:currentManifest,contents:currentContentList}=await buildManifest(pmRoot),currentContents=new Map(currentManifest.files.map((file,index)=>[file,currentContentList[index]])),targetContents=await snapshotContents(path.join(snapshotStore(pmRoot),"objects",targetManifest.fingerprint,"files"),targetManifest.files),currentFiles=new Set(currentManifest.files),targetFiles=new Set(targetManifest.files),changedFiles=new Set([...currentFiles,...targetFiles]);for(const file of changedFiles){const currentContent=currentContents.get(file),targetContent=targetContents.get(file);currentContent!==void 0&&targetContent!==void 0&&currentContent.equals(targetContent)&&changedFiles.delete(file)}const affectedHistoryStreams=currentManifest.files.filter(file=>file.startsWith("history/")&&file.endsWith(".jsonl")).map(file=>{const currentEntries=lineCount(currentContents.get(file)),targetEntries=lineCount(targetContents.get(file));return{path:file,current_entries:currentEntries,target_entries:targetEntries,removed_entries:Math.max(0,currentEntries-targetEntries)}}).filter(entry=>entry.removed_entries>0).sort((left,right)=>left.path.localeCompare(right.path));return{target_fingerprint:targetManifest.fingerprint,current_fingerprint:currentManifest.fingerprint,changed_file_count:changedFiles.size,removed_file_count:[...currentFiles].filter(file=>!targetFiles.has(file)).length,added_file_count:[...targetFiles].filter(file=>!currentFiles.has(file)).length,removed_item_count:[...currentFiles].filter(file=>file.endsWith(".toon")&&!targetFiles.has(file)).length,affected_history_stream_count:affectedHistoryStreams.length,removed_history_entry_count:affectedHistoryStreams.reduce((total,entry)=>total+entry.removed_entries,0),affected_history_streams:affectedHistoryStreams,changes_authoritative_state:currentManifest.fingerprint!==targetManifest.fingerprint}}async function restoreWorkspaceSnapshotWithRecovery(pmRoot,target,options={}){if(options.force!==!0)throw new PmCliError("Workspace snapshot restore requires explicit force confirmation; inspect the impact with planWorkspaceSnapshotRestore or pm workspace snapshot restore <target> --dry-run, then retry with force",EXIT_CODE.USAGE,{code:"workspace_snapshot_force_required",required:"Preview the destructive impact, then explicitly confirm the restore.",why:"A restore replaces the complete authoritative tracker state.",examples:[`pm workspace snapshot restore ${target} --dry-run --json`,`pm workspace snapshot restore ${target} --force --json`],nextSteps:["Review the dry-run counts before retrying with --force."],recovery:{suggested_retry:`pm workspace snapshot restore ${target} --dry-run --json`}});const author=options.author?.trim()||"pm-sdk",lockTtlSeconds=options.lockTtlSeconds??60,lockWaitMs=options.lockWaitMs??5e3,releaseWorkspaceLock=await acquireLock(pmRoot,WORKSPACE_WRITER_LOCK_ID,lockTtlSeconds,author,!1,!1,lockWaitMs),heartbeat=new WorkspaceLockHeartbeat(getLockPath(pmRoot,WORKSPACE_WRITER_LOCK_ID),author,lockTtlSeconds);heartbeat.start(),await heartbeat.refreshNow();let staging,swapStarted=!1,heartbeatStopped=!1;try{const plan=await planWorkspaceSnapshotRestore(pmRoot,target),manifest=await inspectWorkspaceSnapshot(pmRoot,target),recovery=await createWorkspaceSnapshot(pmRoot),fingerprint=manifest.fingerprint,store=snapshotStore(pmRoot),source=path.join(store,"objects",fingerprint,"files"),parent=path.dirname(pmRoot),base=path.basename(pmRoot);staging=path.join(parent,`.${base}.restore-${crypto.randomUUID()}`);const backup=path.join(parent,`.${base}.backup-${crypto.randomUUID()}`);await withSnapshotFilesystemGuard("restore_stage",async()=>{await mkdir(staging,{recursive:!0}),await cp(source,staging,{recursive:!0,force:!1}),await mkdir(path.join(staging,"runtime"),{recursive:!0}),await cp(store,path.join(staging,SNAPSHOT_RUNTIME_PATH),{recursive:!0,force:!1})});const audit=await appendWorkspaceAuditEvent({pmRoot:staging,op:"workspace_snapshot_restore",author,message:options.message??`Restore workspace snapshot ${fingerprint}; recovery snapshot ${recovery.manifest.fingerprint}`,context:{target_fingerprint:fingerprint,pre_restore_fingerprint:recovery.manifest.fingerprint,changed_file_count:plan.changed_file_count,removed_file_count:plan.removed_file_count,removed_item_count:plan.removed_item_count,affected_history_stream_count:plan.affected_history_stream_count,removed_history_entry_count:plan.removed_history_entry_count},lockTtlSeconds,lockWaitMs}),auditHistoryPath=path.relative(staging,audit.historyPath).replaceAll("\\","/");await heartbeat.stop(),heartbeatStopped=!0;const stagedWorkspaceLock=getLockPath(staging,WORKSPACE_WRITER_LOCK_ID);return await mkdir(path.dirname(stagedWorkspaceLock),{recursive:!0}),await writeFile(stagedWorkspaceLock,await readFile(getLockPath(pmRoot,WORKSPACE_WRITER_LOCK_ID)),{flag:"wx"}),swapStarted=!0,await swapWorkspaceSnapshotRootWithActivation(staging,pmRoot,backup,DEFAULT_ATOMIC_OPERATIONS,async()=>{heartbeat.start(),heartbeatStopped=!1,await heartbeat.refreshNow()}),await heartbeat.stop(),heartbeatStopped=!0,{manifest,plan,recovery_fingerprint:recovery.manifest.fingerprint,audit_history_path:auditHistoryPath,audit_operation:"workspace_snapshot_restore"}}catch(error){throw staging!==void 0&&!swapStarted&&await Promise.allSettled([rm(staging,{recursive:!0,force:!0})]),error}finally{try{heartbeatStopped||await heartbeat.stop()}catch{}finally{await releaseWorkspaceLock()}}}async function restoreWorkspaceSnapshot(pmRoot,target){return(await restoreWorkspaceSnapshotWithRecovery(pmRoot,target,{force:!0,message:"Restore requested through the compatibility SDK signature"})).manifest}async function deleteWorkspaceSnapshot(pmRoot,target){validateSnapshotTarget(target);const store=snapshotStore(pmRoot);if(!/^[a-f0-9]{64}$/.test(target))return await removeSnapshotEntry(path.join(store,"refs",`${target}.json`),target,!1),{deleted:"reference",target};const{references}=await listWorkspaceSnapshots(pmRoot);if(references.some(reference=>reference.fingerprint===target))throw new Error(`Snapshot object ${target} is still referenced`);return await removeSnapshotEntry(path.join(store,"objects",target),target,!0),{deleted:"object",target}}export{SNAPSHOT_SCHEMA,WORKSPACE_SNAPSHOT_ACTIONS,_testOnlyWorkspaceSnapshot,createWorkspaceSnapshot,deleteWorkspaceSnapshot,inspectWorkspaceSnapshot,listWorkspaceSnapshots,planWorkspaceSnapshotRestore,publishWorkspaceSnapshotObject,restoreWorkspaceSnapshot,restoreWorkspaceSnapshotWithRecovery,swapWorkspaceSnapshotRoot};
5
6
  //# sourceMappingURL=workspace-snapshot.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]="9189cea6-950f-5594-9321-b7590171297c")}catch(e2){}})();import{isFileMissingError}from"../core/fs/fs-utils.js";import fs from"node:fs/promises";import path from"node:path";const MILLISECONDS_PER_DAY=24*60*60*1e3;const TERMINAL_JOURNAL_STATUSES=new Set(["committed","compensated"]);function readJournalStatusAndTimestamp(raw){let parsed;try{parsed=JSON.parse(raw)}catch{return{status:null,updatedAt:null}}if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){return{status:null,updatedAt:null}}const record=parsed;return{status:typeof record.status==="string"?record.status:null,updatedAt:typeof record.updatedAt==="string"?record.updatedAt:null}}function classifyWorkspaceTransactionJournal(file,status,updatedAt,nowMs,retentionMs){const updatedAtMs=updatedAt===null?Number.NaN:Date.parse(updatedAt);if(status===null||!Number.isFinite(updatedAtMs)){return{entry:{file,status,age_seconds:null,stale:false,reason:"unparseable"},remove:false}}const ageMs=nowMs-updatedAtMs;if(!TERMINAL_JOURNAL_STATUSES.has(status)){return{entry:{file,status,age_seconds:Math.floor(ageMs/1e3),stale:false,reason:"active"},remove:false}}if(!(ageMs>retentionMs)){return{entry:{file,status,age_seconds:Math.floor(ageMs/1e3),stale:false,reason:"fresh"},remove:false}}return{entry:{file,status,age_seconds:Math.floor(ageMs/1e3),stale:true},remove:true}}async function processWorkspaceTransactionJournal(absolutePath,relativePath,fileName,options){const warnings=options.hooks?.onRead?await options.hooks.onRead(absolutePath):[];const journal=readJournalStatusAndTimestamp(await fs.readFile(absolutePath,"utf8"));const decision=classifyWorkspaceTransactionJournal(relativePath,journal.status,journal.updatedAt,options.nowMs,options.retentionMs);if(decision.entry.reason==="unparseable"){warnings.push(`transaction_journal_unparseable:${fileName}`)}if(decision.remove&&!options.dryRun){await fs.rm(absolutePath,{force:true});if(options.hooks?.onWrite){warnings.push(...await options.hooks.onWrite(absolutePath))}}return{decision,warnings}}async function runWorkspaceTransactionGc(pmRoot,options){const{dryRun,hooks}=options;const nowMs=options.now??Date.now();const retentionMs=Math.max(0,options.retentionDays)*MILLISECONDS_PER_DAY;const journalsDir=path.join(pmRoot,"transactions","sdk");const result={scanned:0,removed:[],retained:[],warnings:[],entries:[]};let files;try{files=(await fs.readdir(journalsDir)).filter(file=>file.endsWith(".json")).sort((left,right)=>left.localeCompare(right))}catch(error){if(isFileMissingError(error)){return result}throw error}for(const file of files){const absPath=path.join(journalsDir,file);const relPath=`transactions/sdk/${file}`;const fileResult=await processWorkspaceTransactionJournal(absPath,relPath,file,{dryRun,hooks,nowMs,retentionMs});result.warnings.push(...fileResult.warnings);result.scanned+=1;const{decision}=fileResult;if(!decision.remove){result.retained.push(relPath);result.entries.push(decision.entry);continue}result.removed.push(relPath);result.entries.push(decision.entry)}return result}export{runWorkspaceTransactionGc};
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]="9c0640f0-505c-5f4a-bb7a-daa3cc775239")}catch{}})();import{isFileMissingError}from"../core/fs/fs-utils.js";import fs from"node:fs/promises";import path from"node:path";const MILLISECONDS_PER_DAY=1440*60*1e3,TERMINAL_JOURNAL_STATUSES=new Set(["committed","compensated"]);function readJournalStatusAndTimestamp(raw){let parsed;try{parsed=JSON.parse(raw)}catch{return{status:null,updatedAt:null}}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return{status:null,updatedAt:null};const record=parsed;return{status:typeof record.status=="string"?record.status:null,updatedAt:typeof record.updatedAt=="string"?record.updatedAt:null}}function classifyWorkspaceTransactionJournal(file,status,updatedAt,nowMs,retentionMs){const updatedAtMs=updatedAt===null?Number.NaN:Date.parse(updatedAt);if(status===null||!Number.isFinite(updatedAtMs))return{entry:{file,status,age_seconds:null,stale:!1,reason:"unparseable"},remove:!1};const ageMs=nowMs-updatedAtMs;return TERMINAL_JOURNAL_STATUSES.has(status)?ageMs>retentionMs?{entry:{file,status,age_seconds:Math.floor(ageMs/1e3),stale:!0},remove:!0}:{entry:{file,status,age_seconds:Math.floor(ageMs/1e3),stale:!1,reason:"fresh"},remove:!1}:{entry:{file,status,age_seconds:Math.floor(ageMs/1e3),stale:!1,reason:"active"},remove:!1}}async function processWorkspaceTransactionJournal(absolutePath,relativePath,fileName,options){const warnings=options.hooks?.onRead?await options.hooks.onRead(absolutePath):[],journal=readJournalStatusAndTimestamp(await fs.readFile(absolutePath,"utf8")),decision=classifyWorkspaceTransactionJournal(relativePath,journal.status,journal.updatedAt,options.nowMs,options.retentionMs);return decision.entry.reason==="unparseable"&&warnings.push(`transaction_journal_unparseable:${fileName}`),decision.remove&&!options.dryRun&&(await fs.rm(absolutePath,{force:!0}),options.hooks?.onWrite&&warnings.push(...await options.hooks.onWrite(absolutePath))),{decision,warnings}}async function runWorkspaceTransactionGc(pmRoot,options){const{dryRun,hooks}=options,nowMs=options.now??Date.now(),retentionMs=Math.max(0,options.retentionDays)*MILLISECONDS_PER_DAY,journalsDir=path.join(pmRoot,"transactions","sdk"),result={scanned:0,removed:[],retained:[],warnings:[],entries:[]};let files;try{files=(await fs.readdir(journalsDir)).filter(file=>file.endsWith(".json")).sort((left,right)=>left.localeCompare(right))}catch(error){if(isFileMissingError(error))return result;throw error}for(const file of files){const absPath=path.join(journalsDir,file),relPath=`transactions/sdk/${file}`,fileResult=await processWorkspaceTransactionJournal(absPath,relPath,file,{dryRun,hooks,nowMs,retentionMs});result.warnings.push(...fileResult.warnings),result.scanned+=1;const{decision}=fileResult;if(!decision.remove){result.retained.push(relPath),result.entries.push(decision.entry);continue}result.removed.push(relPath),result.entries.push(decision.entry)}return result}export{runWorkspaceTransactionGc};
2
2
  //# sourceMappingURL=workspace-transaction-gc.js.map