@unbrained/pm-cli 2026.11.2 → 2026.11.4

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 (242) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +24 -0
  3. package/dist/cli/error-guidance.d.ts +23 -35
  4. package/dist/cli/error-guidance.js +4 -3
  5. package/dist/cli/expected-revisions.d.ts +55 -0
  6. package/dist/cli/expected-revisions.js +2 -0
  7. package/dist/cli/main.js +2 -2
  8. package/dist/cli/runtime/field-route-retry.d.ts +15 -0
  9. package/dist/cli/runtime/field-route-retry.js +2 -0
  10. package/dist/cli/runtime/invocation-options.js +1 -1
  11. package/dist/cli-bundle/bundle-manifest.json +1 -1
  12. package/dist/cli-bundle/chunks/{chunk-3A4NVHYS.js → chunk-2GW662DP.js} +2 -2
  13. package/dist/cli-bundle/chunks/chunk-3OXQGGRD.js +115 -0
  14. package/dist/cli-bundle/chunks/chunk-5BVZ32G7.js +2 -0
  15. package/dist/cli-bundle/chunks/chunk-5S6RT5LX.js +9 -0
  16. package/dist/cli-bundle/chunks/chunk-5Z6LWFDL.js +31 -0
  17. package/dist/cli-bundle/chunks/{chunk-RGHLQGEX.js → chunk-6T2V3UIK.js} +2 -2
  18. package/dist/cli-bundle/chunks/{chunk-JRXD7SIL.js → chunk-7PGNAHNW.js} +2 -2
  19. package/dist/cli-bundle/chunks/chunk-7RCI7AAA.js +20 -0
  20. package/dist/cli-bundle/chunks/chunk-AQ5UHHQS.js +2 -0
  21. package/dist/cli-bundle/chunks/chunk-BK2XAQVC.js +2 -0
  22. package/dist/cli-bundle/chunks/{chunk-ABFFRQRO.js → chunk-BRIPGUAO.js} +2 -2
  23. package/dist/cli-bundle/chunks/chunk-BWAXA6S4.js +6 -0
  24. package/dist/cli-bundle/chunks/{chunk-HOGKWJU5.js → chunk-CERNIZLB.js} +66 -66
  25. package/dist/cli-bundle/chunks/chunk-DSCFJTHB.js +122 -0
  26. package/dist/cli-bundle/chunks/{chunk-VEOFWE32.js → chunk-L4BKTPJ6.js} +2 -2
  27. package/dist/cli-bundle/chunks/{chunk-NGRPD3ZO.js → chunk-NPEDFOVQ.js} +2 -2
  28. package/dist/cli-bundle/chunks/{chunk-J3JM36EH.js → chunk-O4ZLEN4T.js} +2 -2
  29. package/dist/cli-bundle/chunks/{chunk-533L6D2N.js → chunk-ODMJ3HIB.js} +3 -3
  30. package/dist/cli-bundle/chunks/{chunk-KJLGBLR3.js → chunk-QN7VCOUU.js} +2 -2
  31. package/dist/cli-bundle/chunks/chunk-QQHMNUZT.js +2 -0
  32. package/dist/cli-bundle/chunks/{chunk-D52QQ7LP.js → chunk-RSAN2YUU.js} +2 -2
  33. package/dist/cli-bundle/chunks/chunk-SRDO2NJU.js +2 -0
  34. package/dist/cli-bundle/chunks/chunk-T56MB6SF.js +2 -0
  35. package/dist/cli-bundle/chunks/chunk-TX2W6G37.js +3 -0
  36. package/dist/cli-bundle/chunks/{chunk-GK2CHAT3.js → chunk-UJMQP2HP.js} +2 -2
  37. package/dist/cli-bundle/chunks/{indexed-receipt-blobs-IEJ2QOW3.js → indexed-receipt-blobs-I6RQGD6Y.js} +2 -2
  38. package/dist/cli-bundle/chunks/item-revision-UAZOBP2Q.js +2 -0
  39. package/dist/cli-bundle/chunks/item-transaction-N5F4LXYV.js +2 -0
  40. package/dist/cli-bundle/chunks/mutation-admission-QZQI2NN5.js +2 -0
  41. package/dist/cli-bundle/chunks/{register-list-query-NZTK3AXA.js → register-list-query-P3NOKQUA.js} +2 -2
  42. package/dist/cli-bundle/chunks/{register-mutation-2OFAMOVH.js → register-mutation-A6I5K5N6.js} +2 -2
  43. package/dist/cli-bundle/chunks/register-operations-SPKB3TNM.js +2 -0
  44. package/dist/cli-bundle/chunks/register-setup-ZZRHJ4IS.js +2 -0
  45. package/dist/cli-bundle/chunks/{settlement-hook-UTCEZBFT.js → settlement-hook-JHXLUBEN.js} +2 -2
  46. package/dist/cli-bundle/chunks/{stage-VLI4OBVX.js → stage-L3T725DS.js} +2 -2
  47. package/dist/cli-bundle/focused-chunks/chunk-5NGNO54M.js +44 -0
  48. package/dist/cli-bundle/focused-chunks/{chunk-PCCZ72C3.js → chunk-A2246ZM7.js} +54 -54
  49. package/dist/cli-bundle/focused-chunks/chunk-B6U44WPW.js +2 -0
  50. package/dist/cli-bundle/focused-chunks/chunk-BAW3DGQO.js +91 -0
  51. package/dist/cli-bundle/focused-chunks/chunk-BHNY3KPJ.js +2 -0
  52. package/dist/cli-bundle/focused-chunks/chunk-C3O6JJPO.js +2 -0
  53. package/dist/cli-bundle/focused-chunks/{chunk-745IDMTD.js → chunk-C7UX2ZI3.js} +2 -2
  54. package/dist/cli-bundle/focused-chunks/chunk-CBG67HUP.js +23 -0
  55. package/dist/cli-bundle/focused-chunks/{chunk-NJFMG3IK.js → chunk-CO2DNPH7.js} +2 -2
  56. package/dist/cli-bundle/focused-chunks/chunk-CXTDEQ3N.js +8 -0
  57. package/dist/cli-bundle/focused-chunks/chunk-FEPE2CE4.js +2 -0
  58. package/dist/cli-bundle/focused-chunks/chunk-FFO7RBLN.js +2 -0
  59. package/dist/cli-bundle/focused-chunks/{chunk-QNXXOFLQ.js → chunk-FXFDVM5O.js} +2 -2
  60. package/dist/cli-bundle/focused-chunks/{chunk-QVFE5LIX.js → chunk-G6ERMFJ5.js} +2 -2
  61. package/dist/cli-bundle/focused-chunks/chunk-I5LGPUWH.js +2 -0
  62. package/dist/cli-bundle/focused-chunks/{chunk-MQVBWFJF.js → chunk-IDAYTYNN.js} +2 -2
  63. package/dist/cli-bundle/focused-chunks/chunk-J3YOATXR.js +80 -0
  64. package/dist/cli-bundle/focused-chunks/{chunk-3UD6F2KQ.js → chunk-J6FDCAMH.js} +2 -2
  65. package/dist/cli-bundle/focused-chunks/chunk-J7M52SCZ.js +2 -0
  66. package/dist/cli-bundle/focused-chunks/chunk-JQS7TYQ6.js +12 -0
  67. package/dist/cli-bundle/focused-chunks/chunk-MEJKELWC.js +26 -0
  68. package/dist/cli-bundle/focused-chunks/chunk-PMKR4MJI.js +2 -0
  69. package/dist/cli-bundle/focused-chunks/chunk-PNPYQDHU.js +2 -0
  70. package/dist/cli-bundle/focused-chunks/chunk-Q4OIRSKL.js +2 -0
  71. package/dist/cli-bundle/focused-chunks/{chunk-I4Z2SCV5.js → chunk-QEVJ3Y67.js} +2 -2
  72. package/dist/cli-bundle/focused-chunks/{chunk-Q23K6WLV.js → chunk-SDLIUZEL.js} +2 -2
  73. package/dist/cli-bundle/focused-chunks/chunk-TFYTTDAK.js +2 -0
  74. package/dist/cli-bundle/focused-chunks/chunk-W3CSX6GI.js +3 -0
  75. package/dist/cli-bundle/focused-chunks/{chunk-B6OOKKOX.js → chunk-Y5GOUUYJ.js} +3 -3
  76. package/dist/cli-bundle/focused-chunks/{indexed-receipt-blobs-FT3KF6VJ.js → indexed-receipt-blobs-7XGVHYAO.js} +2 -2
  77. package/dist/cli-bundle/focused-chunks/item-revision-L6GVT42D.js +2 -0
  78. package/dist/cli-bundle/focused-chunks/item-transaction-GYGP264N.js +2 -0
  79. package/dist/cli-bundle/focused-chunks/mutation-admission-UWTH56OD.js +2 -0
  80. package/dist/cli-bundle/focused-chunks/{settlement-hook-KMIBD4F2.js → settlement-hook-H56537UV.js} +2 -2
  81. package/dist/cli-bundle/focused-chunks/{stage-6B3O2GZ6.js → stage-WRSNJ7VI.js} +2 -2
  82. package/dist/cli-bundle/main.js +30 -29
  83. package/dist/cli-bundle/sdk-authoring.js +1 -1
  84. package/dist/cli-bundle/sdk-contracts.js +5 -5
  85. package/dist/cli-bundle/sdk-core.js +1 -1
  86. package/dist/cli-bundle/sdk-governance.js +1 -1
  87. package/dist/cli-bundle/sdk-graph.js +1 -1
  88. package/dist/cli-bundle/sdk-merge.js +57 -57
  89. package/dist/cli-bundle/sdk-query.js +1 -1
  90. package/dist/cli-bundle/sdk-runtime.js +1 -1
  91. package/dist/cli-bundle/sdk-testing.js +1 -1
  92. package/dist/cli-bundle/sdk.js +11 -11
  93. package/dist/core/config/positional-value.d.ts +1 -1
  94. package/dist/core/config/positional-value.js +1 -1
  95. package/dist/core/extensions/extension-hook-runtime.js +1 -1
  96. package/dist/core/extensions/item-fields.d.ts +1 -1
  97. package/dist/core/extensions/item-fields.js +1 -1
  98. package/dist/core/extensions/reserved-host-flags.js +1 -1
  99. package/dist/core/history/history-rewrite.js +1 -1
  100. package/dist/core/schema/runtime-field-values.d.ts +30 -0
  101. package/dist/core/schema/runtime-field-values.js +1 -1
  102. package/dist/core/sentry/helpers.js +1 -1
  103. package/dist/core/sentry/instrument.js +1 -1
  104. package/dist/core/shared/command-types.d.ts +7 -0
  105. package/dist/core/shared/error-details.d.ts +98 -0
  106. package/dist/core/shared/error-details.js +2 -0
  107. package/dist/core/shared/errors.d.ts +37 -0
  108. package/dist/core/shared/errors.js +1 -1
  109. package/dist/core/store/item-mutation-precondition.d.ts +70 -6
  110. package/dist/core/store/item-mutation-precondition.js +1 -1
  111. package/dist/core/store/item-store.js +1 -1
  112. package/dist/core/store/settings-validator.js +1 -1
  113. package/dist/core/store/settings.js +1 -1
  114. package/dist/mcp/server.js +2 -2
  115. package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -1
  116. package/dist/sdk/cli-contracts/completeness.js +1 -1
  117. package/dist/sdk/cli-contracts/enum-contracts.d.ts +11 -0
  118. package/dist/sdk/cli-contracts/enum-contracts.js +1 -1
  119. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
  120. package/dist/sdk/cli-contracts/registration-helpers.js +1 -1
  121. package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
  122. package/dist/sdk/cli-contracts/tool-schema.js +1 -1
  123. package/dist/sdk/cli-program.js +1 -1
  124. package/dist/sdk/config.d.ts +1 -1
  125. package/dist/sdk/config.js +1 -1
  126. package/dist/sdk/environment/project-runtime-compatibility.js +1 -1
  127. package/dist/sdk/errors.d.ts +6 -2
  128. package/dist/sdk/errors.js +1 -1
  129. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  130. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
  131. package/dist/sdk/governance/validate.js +1 -1
  132. package/dist/sdk/history/salvage.js +3 -3
  133. package/dist/sdk/history-compact.d.ts +7 -1
  134. package/dist/sdk/history-compact.js +1 -1
  135. package/dist/sdk/history-repair.d.ts +2 -1
  136. package/dist/sdk/history-repair.js +1 -1
  137. package/dist/sdk/index.d.ts +4 -1
  138. package/dist/sdk/index.js +1 -1
  139. package/dist/sdk/lifecycle/checkpoint-rollback.d.ts +10 -2
  140. package/dist/sdk/lifecycle/checkpoint-rollback.js +1 -1
  141. package/dist/sdk/lifecycle/claim.js +1 -1
  142. package/dist/sdk/lifecycle/close-many.d.ts +11 -2
  143. package/dist/sdk/lifecycle/close-many.js +1 -1
  144. package/dist/sdk/lifecycle/close.d.ts +15 -0
  145. package/dist/sdk/lifecycle/close.js +1 -1
  146. package/dist/sdk/lifecycle/core-field-recovery.d.ts +26 -0
  147. package/dist/sdk/lifecycle/core-field-recovery.js +1 -1
  148. package/dist/sdk/lifecycle/create.js +1 -1
  149. package/dist/sdk/lifecycle/item-revision.d.ts +162 -0
  150. package/dist/sdk/lifecycle/item-revision.js +2 -0
  151. package/dist/sdk/lifecycle/restore.js +1 -1
  152. package/dist/sdk/lifecycle/start-blockers.d.ts +52 -0
  153. package/dist/sdk/lifecycle/start-blockers.js +2 -0
  154. package/dist/sdk/lifecycle/task-composition.d.ts +11 -0
  155. package/dist/sdk/lifecycle/task-composition.js +1 -1
  156. package/dist/sdk/lifecycle/update-many.d.ts +11 -2
  157. package/dist/sdk/lifecycle/update-many.js +1 -1
  158. package/dist/sdk/lifecycle/update.js +2 -2
  159. package/dist/sdk/public-surface.json +1 -1
  160. package/dist/sdk/query/declared-blockers.d.ts +16 -0
  161. package/dist/sdk/query/declared-blockers.js +2 -0
  162. package/dist/sdk/query/get.d.ts +7 -0
  163. package/dist/sdk/query/get.js +1 -1
  164. package/dist/sdk/query/projection-contracts.js +1 -1
  165. package/dist/sdk/runtime-input.d.ts +12 -0
  166. package/dist/sdk/runtime-input.js +1 -1
  167. package/dist/sdk/runtime.d.ts +11 -1
  168. package/dist/sdk/runtime.js +1 -1
  169. package/dist/sdk/structured-mutations.js +1 -1
  170. package/dist/sdk/test/batch.js +2 -2
  171. package/dist/sdk/test/entry.d.ts +5 -0
  172. package/dist/sdk/test/entry.js +2 -2
  173. package/dist/sdk/test/execution.d.ts +1 -2
  174. package/dist/sdk/test/execution.js +2 -2
  175. package/dist/sdk/test/linked-command-detection.d.ts +10 -0
  176. package/dist/sdk/test/linked-command-detection.js +1 -1
  177. package/dist/sdk/test/update.d.ts +2 -0
  178. package/dist/sdk/test/update.js +1 -1
  179. package/dist/sdk/workspace-transaction.d.ts +17 -6
  180. package/dist/sdk/workspace-transaction.js +1 -1
  181. package/dist/types.d.ts +6 -0
  182. package/dist/types.js +1 -1
  183. package/docs/COMMANDS.md +91 -0
  184. package/docs/CONFIGURATION.md +1 -0
  185. package/docs/EXTENSIONS.md +2 -2
  186. package/docs/LINKED_TEST_EDITS.md +38 -5
  187. package/docs/SDK.md +185 -1
  188. package/docs/agent-task-token-baseline.json +1 -1
  189. package/docs/generated/FLAG_LEXICON_BUDGETS.md +111 -111
  190. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +15 -3
  191. package/marketplace.json +1 -1
  192. package/package.json +1 -1
  193. package/packages/pm-beads/package.json +1 -1
  194. package/packages/pm-calendar/package.json +1 -1
  195. package/packages/pm-command-kit/package.json +1 -1
  196. package/packages/pm-digital-twin/package.json +1 -1
  197. package/packages/pm-governance-audit/package.json +1 -1
  198. package/packages/pm-guide-shell/package.json +1 -1
  199. package/packages/pm-kanban/package.json +1 -1
  200. package/packages/pm-lifecycle-hooks/package.json +1 -1
  201. package/packages/pm-linked-test-adapters/package.json +1 -1
  202. package/packages/pm-search-advanced/package.json +1 -1
  203. package/packages/pm-templates/package.json +1 -1
  204. package/packages/pm-todos/package.json +1 -1
  205. package/packages/pm-vcs/package.json +1 -1
  206. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  207. package/plugins/pm-claude/package.json +1 -1
  208. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  209. package/plugins/pm-codex/package.json +1 -1
  210. package/plugins/pm-codex/plugin.json +1 -1
  211. package/runtime-dependencies.json +1 -1
  212. package/dist/cli-bundle/chunks/chunk-3ZQQVJT2.js +0 -20
  213. package/dist/cli-bundle/chunks/chunk-4HW253W2.js +0 -2
  214. package/dist/cli-bundle/chunks/chunk-4OELCF3O.js +0 -2
  215. package/dist/cli-bundle/chunks/chunk-BFZUJ5QP.js +0 -115
  216. package/dist/cli-bundle/chunks/chunk-DAZFCSDV.js +0 -2
  217. package/dist/cli-bundle/chunks/chunk-EN27ZQSV.js +0 -2
  218. package/dist/cli-bundle/chunks/chunk-K46GDAKX.js +0 -6
  219. package/dist/cli-bundle/chunks/chunk-OJR2YGXF.js +0 -31
  220. package/dist/cli-bundle/chunks/chunk-QHHFXNSQ.js +0 -3
  221. package/dist/cli-bundle/chunks/chunk-ZNWDYDFF.js +0 -129
  222. package/dist/cli-bundle/chunks/item-transaction-JHPBH6N7.js +0 -2
  223. package/dist/cli-bundle/chunks/mutation-admission-QUNQZCZ5.js +0 -2
  224. package/dist/cli-bundle/chunks/register-operations-RFMM5KZ6.js +0 -2
  225. package/dist/cli-bundle/chunks/register-setup-6B6Q7M5L.js +0 -2
  226. package/dist/cli-bundle/focused-chunks/chunk-4NVPDZLX.js +0 -12
  227. package/dist/cli-bundle/focused-chunks/chunk-4UUE3YXZ.js +0 -2
  228. package/dist/cli-bundle/focused-chunks/chunk-5UDDRPYR.js +0 -8
  229. package/dist/cli-bundle/focused-chunks/chunk-AK2CI2GI.js +0 -2
  230. package/dist/cli-bundle/focused-chunks/chunk-EJJWOFP5.js +0 -91
  231. package/dist/cli-bundle/focused-chunks/chunk-FUGYXUUL.js +0 -80
  232. package/dist/cli-bundle/focused-chunks/chunk-HMXVTWIV.js +0 -3
  233. package/dist/cli-bundle/focused-chunks/chunk-JLN5CFYM.js +0 -2
  234. package/dist/cli-bundle/focused-chunks/chunk-K4FMZB4Y.js +0 -23
  235. package/dist/cli-bundle/focused-chunks/chunk-PF553UVP.js +0 -44
  236. package/dist/cli-bundle/focused-chunks/chunk-RUCG6UWN.js +0 -2
  237. package/dist/cli-bundle/focused-chunks/chunk-SGWYNU7T.js +0 -2
  238. package/dist/cli-bundle/focused-chunks/chunk-TGS5RXBY.js +0 -26
  239. package/dist/cli-bundle/focused-chunks/chunk-WD43E7RU.js +0 -2
  240. package/dist/cli-bundle/focused-chunks/chunk-YM4AMP7H.js +0 -2
  241. package/dist/cli-bundle/focused-chunks/item-transaction-F4SN7TXJ.js +0 -2
  242. package/dist/cli-bundle/focused-chunks/mutation-admission-7R2FXJ5O.js +0 -2
@@ -91,6 +91,30 @@ reason:string;
91
91
  /** Value that configures or reports next best command for this contract. */
92
92
  next_best_command?:string;
93
93
  }
94
+ /** One JSON value inside producer-owned error diagnostics. */
95
+ export type PmCliErrorDetailValue = null | boolean | number | string | PmCliErrorDetailValue[] | {
96
+ [key:string]:PmCliErrorDetailValue;
97
+ };
98
+ /**
99
+ * Producer-owned structured diagnostics for an expected error (GH-1631). The
100
+ * host renders them as-is in structured error output, bounded by
101
+ * `PM_CLI_ERROR_DETAILS_LIMITS`, and never sends them to telemetry or crash
102
+ * reporting.
103
+ */
104
+ export type PmCliErrorDetails = {
105
+ [key:string]:PmCliErrorDetailValue;
106
+ };
107
+ /** Why a producer's diagnostics could not be rendered. */
108
+ export type PmCliErrorDetailsRejection = "not_plain_object" | "unsupported_value" | "non_finite_number" | "malformed_unicode" | "reserved_key" | "depth_limit" | "byte_limit" | "diagnostic_budget";
109
+ /** Host-set receipt that replaces diagnostics the host could not render. */
110
+ export interface PmCliErrorDetailsOmission {
111
+ /** Stable reason the diagnostics were withheld. */
112
+ reason:PmCliErrorDetailsRejection;
113
+ /** Bounded JSON path of the first offending value, when the shape was refused. */
114
+ path?:string;
115
+ /** Byte ceiling that applied. */
116
+ byte_limit:number;
117
+ }
94
118
  /** Documents the pm cli error context payload exchanged by command, SDK, and package integrations. */
95
119
  export interface PmCliErrorContext {
96
120
  /** Durable writes completed before refusal; paths are relative to the selected tracker. */
@@ -307,6 +331,19 @@ expected_revision?:string | null;
307
331
  current_revision?:string | null;
308
332
  /** Value that configures or reports recovery for this contract. */
309
333
  recovery?:PmCliErrorRecoveryPayload;
334
+ /**
335
+ * Producer-owned structured diagnostics: plain JSON the host renders whole
336
+ * in `--json`, text and MCP error output when it fits the declared ceiling,
337
+ * and otherwise replaces with a `details_omitted` receipt. Never sent to
338
+ * telemetry or crash reporting.
339
+ */
340
+ details?:PmCliErrorDetails;
341
+ /**
342
+ * Host-set receipt recorded instead of `details` when they could not be
343
+ * admitted (for example oversized at construction). Producers set `details`;
344
+ * the host owns this field and never sends it to telemetry or crash reporting.
345
+ */
346
+ details_omitted?:PmCliErrorDetailsOmission;
310
347
  }
311
348
  /** Implements the exported pm cli error runtime abstraction for core/shared/errors.ts. */
312
349
  export declare class PmCliError extends Error {
@@ -1,2 +1,2 @@
1
- (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="59ace77e-9dc1-59e8-aa2e-ee7364e04773")}catch{}})();class PmCliError extends Error{exitCode;code;context;constructor(message,exitCode,context={}){super(message),this.name="PmCliError",this.exitCode=exitCode,this.context=context,this.code=context.code}}export{PmCliError};
1
+ (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9896afd0-b833-5b30-b047-4881891d3976")}catch{}})();class PmCliError extends Error{exitCode;code;context;constructor(message,exitCode,context={}){super(message),this.name="PmCliError",this.exitCode=exitCode,this.context=context,this.code=context.code}}export{PmCliError};
2
2
  //# sourceMappingURL=errors.js.map
@@ -10,10 +10,74 @@ historyContext?:Record<string,unknown>;
10
10
  }
11
11
  /** Scope a target-specific precondition to an awaited mutation without affecting concurrent callers. */
12
12
  export declare function runWithItemMutationPrecondition<T>(condition:ItemMutationPrecondition,operation:() => Promise<T>):Promise<T>;
13
- /** Evaluate matching preconditions only after the item lock has been acquired and its document read. */
14
- export declare function assertItemMutationPreconditions(pmRoot:string,document:ItemDocument):void;
15
- /** Notify matching scoped guards of their own committed document before releasing the item lock. */
16
- export declare function advanceItemMutationPreconditions(pmRoot:string,document:ItemDocument):void;
17
- /** Collect target-scoped immutable attribution without attributing another caller's writes. */
18
- export declare function itemMutationPreconditionHistoryContext(pmRoot:string,document:ItemDocument):Record<string,unknown>;
13
+ /** One caller-declared revision of one item, as returned by `item_hash` reads. */
14
+ interface ItemRevisionScopeEntry {
15
+ /** Revision the caller decided on. */
16
+ declared:string;
17
+ /** Revision the next locked write must find; advances past this scope's own commits. */
18
+ expected:string;
19
+ /** Whether any locked write evaluated this expectation. */
20
+ checked:boolean;
21
+ /**
22
+ * Whether this scope durably committed a write to the item. Tracked apart from
23
+ * `expected`, which can return to `declared` (a restore then delete reproduces
24
+ * the declared tombstone).
25
+ */
26
+ committed:boolean;
27
+ }
28
+ /**
29
+ * Mutable expected-revision scope for one invocation. Hosts open it before the
30
+ * command runs and bind it once the tracker root and canonical ids are known,
31
+ * so expectations reach every locked item write the invocation makes.
32
+ */
33
+ export interface ItemRevisionScope {
34
+ /** Resolved tracker root, unset until the host binds the scope. */
35
+ pmRoot?:string;
36
+ /** Canonical item id to declared revision state. */
37
+ entries:Map<string,ItemRevisionScopeEntry>;
38
+ }
39
+ /** Create an empty, unbound expected-revision scope. */
40
+ export declare function createItemRevisionScope():ItemRevisionScope;
41
+ /** Run an operation with an expected-revision scope visible to every locked item write it makes. */
42
+ export declare function runWithItemRevisionScope<T>(scope:ItemRevisionScope,operation:() => Promise<T>):Promise<T>;
43
+ /**
44
+ * Bind canonical expectations to a scope. The same id may repeat only with the
45
+ * same revision, because two different revisions of one item cannot both hold.
46
+ */
47
+ export declare function bindItemRevisionScope(scope:ItemRevisionScope,pmRoot:string,expectations:readonly {
48
+ id:string;
49
+ itemHash:string;
50
+ }[]):void;
51
+ /** Report which bound expectations a locked write evaluated, in binding order. */
52
+ export declare function itemRevisionScopeReceipt(scope:ItemRevisionScope):{
53
+ checked:string[];
54
+ unchecked:string[];
55
+ };
56
+ /**
57
+ * Whether any active scope declared a revision on this tracker, so writers that
58
+ * must read a document to learn its embedded id can skip that read otherwise.
59
+ */
60
+ export declare function hasActiveItemRevisionScope(pmRoot:string):boolean;
61
+ /**
62
+ * Refuse a guarded write over a live item that cannot be read as a document
63
+ * (restore recovering corrupt bytes). No declared revision describes those bytes,
64
+ * so the guard refuses rather than judging the history reconstruction restore
65
+ * would write from. `current_revision` is the SHA-256 of the unreadable text.
66
+ */
67
+ export declare function assertItemRevisionExpectationsOnUnreadable(pmRoot:string,targetId:string,raw:string):void;
68
+ /**
69
+ * Evaluate matching preconditions only after the item lock has been acquired
70
+ * and its document read. `targetId` names the locked item explicitly, so a
71
+ * deleted item's empty tombstone document is still judged against its own
72
+ * expectations instead of matching nothing.
73
+ */
74
+ export declare function assertItemMutationPreconditions(pmRoot:string,document:ItemDocument,targetId?:string):void;
75
+ /**
76
+ * Notify matching scoped guards of their own committed document (a tombstone
77
+ * after delete) before releasing the item lock. `aliasIds` carries identities
78
+ * the committed document no longer has, such as a deleted item's embedded id.
79
+ */
80
+ export declare function advanceItemMutationPreconditions(pmRoot:string,document:ItemDocument,targetId?:string,aliasIds?:readonly string[]):void;
81
+ /** Collect target-scoped immutable attribution (keyed by either identity of the locked item) without attributing another caller's writes. */
82
+ export declare function itemMutationPreconditionHistoryContext(pmRoot:string,ids:readonly unknown[]):Record<string,unknown>;
19
83
  export {};
@@ -1,2 +1,2 @@
1
- (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="39bf765c-1374-5ba5-b8a9-44137f80c976")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import path from"node:path";const preconditions=new AsyncLocalStorage;function runWithItemMutationPrecondition(condition,operation){return preconditions.run([...preconditions.getStore()??[],{...condition,pmRoot:path.resolve(condition.pmRoot)}],operation)}function assertItemMutationPreconditions(pmRoot,document){for(const condition of preconditions.getStore()??[])condition.pmRoot===path.resolve(pmRoot)&&condition.id===document.metadata.id&&condition.validate(document)}function advanceItemMutationPreconditions(pmRoot,document){for(const condition of preconditions.getStore()??[])condition.pmRoot===path.resolve(pmRoot)&&condition.id===document.metadata.id&&condition.committed?.(document)}function itemMutationPreconditionHistoryContext(pmRoot,document){return Object.assign({},...(preconditions.getStore()??[]).filter(condition=>condition.pmRoot===path.resolve(pmRoot)&&condition.id===document.metadata.id).map(condition=>condition.historyContext))}export{advanceItemMutationPreconditions,assertItemMutationPreconditions,itemMutationPreconditionHistoryContext,runWithItemMutationPrecondition};
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]="0463fdc5-c219-53ba-bf61-9d9635367cb1")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{realpathSync}from"node:fs";import path from"node:path";import{hashDocument}from"../history/history.js";import{sha256Hex}from"../shared/serialization.js";import{EXIT_CODE}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";const preconditions=new AsyncLocalStorage;function runWithItemMutationPrecondition(condition,operation){return preconditions.run([...preconditions.getStore()??[],{...condition,pmRoot:path.resolve(condition.pmRoot)}],operation)}const REVISION_SCOPES_KEY=Symbol.for("@unbrained/pm-cli/item-revision-scopes"),revisionScopeRegistry=globalThis,revisionScopes=revisionScopeRegistry[REVISION_SCOPES_KEY]??=new AsyncLocalStorage;function canonicalTrackerRoot(pmRoot){const resolved=path.resolve(pmRoot);try{return realpathSync.native(resolved)}catch{return resolved}}function createItemRevisionScope(){return{entries:new Map}}function runWithItemRevisionScope(scope,operation){return revisionScopes.run([...revisionScopes.getStore()??[],scope],operation)}function bindItemRevisionScope(scope,pmRoot,expectations){const resolvedRoot=canonicalTrackerRoot(pmRoot);if(scope.pmRoot!==void 0&&scope.pmRoot!==resolvedRoot)throw new PmCliError("An expected-revision scope is already bound to another tracker.",EXIT_CODE.USAGE,{code:"expected_revision_scope_conflict",required:"Bind expected item revisions for one tracker per scope."});scope.pmRoot=resolvedRoot;for(const{id,itemHash}of expectations){const existing=scope.entries.get(id);if(existing!==void 0&&existing.declared!==itemHash)throw new PmCliError(`Item ${id} has two different expected revisions.`,EXIT_CODE.USAGE,{code:"expected_revision_duplicate",item_id:id,required:"Declare at most one expected revision per item."});scope.entries.set(id,existing??{declared:itemHash,expected:itemHash,checked:!1,committed:!1})}}function itemRevisionScopeReceipt(scope){const entries=[...scope.entries.entries()];return{checked:entries.filter(([,entry])=>entry.checked).map(([id])=>id),unchecked:entries.filter(([,entry])=>!entry.checked).map(([id])=>id)}}function matchingRevisionEntries(pmRoot,ids){const scopes=revisionScopes.getStore()??[];if(scopes.length===0)return[];const resolvedRoot=canonicalTrackerRoot(pmRoot),keys=new Set(ids.filter(id=>typeof id=="string"));return[...new Set(scopes.flatMap(scope=>scope.pmRoot===resolvedRoot?[...keys].flatMap(key=>scope.entries.get(key)??[]):[]))]}function hasActiveItemRevisionScope(pmRoot){const resolvedRoot=canonicalTrackerRoot(pmRoot);return(revisionScopes.getStore()??[]).some(scope=>scope.pmRoot===resolvedRoot&&scope.entries.size>0)}function assertItemRevisionExpectations(pmRoot,document,targetId){const entries=matchingRevisionEntries(pmRoot,[targetId,document.metadata.id]);entries.length>0&&assertRevisionEntries(entries,targetId,hashDocument(document),!1)}function assertItemRevisionExpectationsOnUnreadable(pmRoot,targetId,raw){const entries=matchingRevisionEntries(pmRoot,[targetId]);entries.length>0&&assertRevisionEntries(entries,targetId,sha256Hex(raw),!0)}function assertRevisionEntries(entries,targetId,current,unreadable){for(const entry of entries)if(entry.checked=!0,!(!unreadable&&entry.expected===current))throw new PmCliError(`Item ${targetId} is no longer at the expected revision ${entry.expected.slice(0,12)}${unreadable?" (its live document cannot be read)":""}; refusing to write over a revision this decision did not see.${entry.committed?" Earlier writes by this same invocation already committed.":" Nothing was written to this item."}`,EXIT_CODE.CONFLICT,{code:"item_revision_conflict",item_id:targetId,expected_revision:entry.expected,current_revision:current,required:unreadable?`Recover ${targetId} without --expect-hash (pm restore ${targetId} <version>), since no declared revision describes an unreadable document.`:`Re-read ${targetId} (pm get ${targetId} --json reports item_hash), decide again against the current revision, then retry with --expect-hash <item_hash>.`,why:"The caller declared the revision its decision was based on, and another write changed the item before this locked write.",examples:[`pm get ${targetId} --fields item_hash --json`,`pm history ${targetId} --limit 5`],nextSteps:[`pm get ${targetId} --json`,`pm history ${targetId} --limit 5`]})}function assertItemMutationPreconditions(pmRoot,document,targetId=document.metadata.id){assertItemRevisionExpectations(pmRoot,document,targetId);for(const condition of conditionsFor(pmRoot,[targetId,document.metadata.id]))condition.validate(document)}function conditionsFor(pmRoot,ids){const resolvedRoot=path.resolve(pmRoot);return(preconditions.getStore()??[]).filter(condition=>condition.pmRoot===resolvedRoot&&ids.includes(condition.id))}function advanceItemMutationPreconditions(pmRoot,document,targetId=document.metadata.id,aliasIds=[]){const entries=matchingRevisionEntries(pmRoot,[targetId,document.metadata.id,...aliasIds]);if(entries.length>0){const committed=hashDocument(document);for(const entry of entries)entry.expected=committed,entry.committed=!0}for(const condition of conditionsFor(pmRoot,[targetId,document.metadata.id,...aliasIds]))condition.committed?.(document)}function itemMutationPreconditionHistoryContext(pmRoot,ids){return Object.assign({},...conditionsFor(pmRoot,ids).map(condition=>condition.historyContext))}export{advanceItemMutationPreconditions,assertItemMutationPreconditions,assertItemRevisionExpectationsOnUnreadable,bindItemRevisionScope,createItemRevisionScope,hasActiveItemRevisionScope,itemMutationPreconditionHistoryContext,itemRevisionScopeReceipt,runWithItemMutationPrecondition,runWithItemRevisionScope};
2
2
  //# sourceMappingURL=item-mutation-precondition.js.map
@@ -1,2 +1,2 @@
1
- (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8266acd6-5564-5d56-8025-82608136296d")}catch{}})();import fs from"node:fs/promises";import{buildDeletedItemError}from"../history/tombstone.js";import{normalizeHistoryOperationForWrite}from"../history/operation-contract.js";import{enforceWorkflowMutation}from"../policy/workflow-policy-store.js";import{recordItemMetadataEnumeration}from"./item-metadata-read-work.js";import{advanceItemMutationPreconditions,assertItemMutationPreconditions,itemMutationPreconditionHistoryContext}from"./item-mutation-precondition.js";import{checkpointMutationHistoryContext}from"../checkpoint/mutation-context.js";import path from"node:path";import{getActiveExtensionRegistrations,projectAfterCommandItemSnapshot,recordAfterCommandAffectedItem,runActiveOnReadHooks,runActiveBeforeMutationHooks,runActiveOnWriteHooks,runActiveServiceOverride}from"../extensions/index.js";import{collectRegisteredItemFieldNames}from"../extensions/item-fields.js";import{EMPTY_CANONICAL_DOCUMENT,EXIT_CODE,TYPE_TO_FOLDER}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{levenshteinDistanceWithinLimit}from"../shared/levenshtein.js";import{appendHistoryEntry,createHistoryEntry}from"../history/history.js";import{enforceHistoryStreamPolicyForItem}from"../history/history-stream-policy.js";import{canonicalDocument,parseItemDocument,serializeItemDocument}from"../item/item-format.js";import{resolveItemTypeRegistry}from"../item/type-registry.js";import{effectiveItemFormatVersion,requiredItemFormatVersion}from"../item/item-format-version.js";import{assertProjectRuntimeFormatGuard}from"../../sdk/environment/project-runtime-compatibility.js";import{acquireLockLease}from"../lock/lock.js";import{isFileMissingError,writeFileAtomic}from"../fs/fs-utils.js";import{isUtf8}from"node:buffer";import{normalizeItemId,normalizeRawItemId}from"../item/id.js";import{acquireItemMetadataDerivedIndexLock,listAllDocumentCandidatesCached,listAllDocumentsCached,listAllDocumentsCachedLight,refreshItemMetadataDerivedIndex}from"./item-metadata-cache.js";import{getHistoryPath,getItemPath,ITEM_FILE_EXTENSIONS,resolveWorkspaceRoot}from"./paths.js";import{resolveGovernanceKnobs}from"./settings.js";import{assertReadableTrackerRoot}from"./tracker-preflight.js";import{resolveClaimPrincipal}from"../shared/author.js";import{nowIso}from"../shared/time.js";async function fileExists(targetPath){try{return await fs.access(targetPath),!0}catch{return!1}}function isErrno(error,code){return typeof error=="object"&&error!==null&&"code"in error&&error.code===code}function appendWarning(warnings,warning){warnings&&(warnings.includes(warning)||warnings.push(warning))}function resolveActiveExtensionFieldNames(explicit){return explicit??collectRegisteredItemFieldNames(getActiveExtensionRegistrations())}function resolveItemFormatSearchOrder(preferredFormat){return preferredFormat==="toon"?["toon","json_markdown"]:preferredFormat==="json_markdown"?["json_markdown","toon"]:["toon","json_markdown"]}async function locateItem(pmRoot,rawId,idPrefix="pm-",preferredFormat,typeToFolder=TYPE_TO_FOLDER){const trimmedRawId=rawId.trim(),exactRawId=trimmedRawId.startsWith("#")?trimmedRawId.slice(1):trimmedRawId;if(exactRawId.length===0)return null;const normalizedId=normalizeItemId(rawId,idPrefix),rawNormalizedId=normalizeRawItemId(rawId),candidateIds=[...new Set([exactRawId,normalizedId,rawNormalizedId])].filter(candidateId=>candidateId.length>0),entries=Object.entries(typeToFolder),searchOrder=resolveItemFormatSearchOrder(preferredFormat);for(const candidateId of candidateIds){const matches=new Map;for(const[type]of entries)for(const itemFormat of searchOrder){const itemPath=getItemPath(pmRoot,type,candidateId,itemFormat,typeToFolder);await fileExists(itemPath)&&matches.set(itemPath,matches.get(itemPath)??{id:candidateId,type,itemPath,item_format:itemFormat})}if(matches.size>1){const paths=[...matches.keys()].map(itemPath=>path.relative(pmRoot,itemPath).split(path.sep).join("/")).sort();throw new PmCliError(`Item ${candidateId} has ambiguous identity across ${paths.join(", ")}. Preserve both documents and inspect pm ops validate --check-storage-integrity before resolving the collision.`,EXIT_CODE.CONFLICT,{code:"item_identity_ambiguous",item_id:candidateId,paths})}for(const match of matches.values())return match}return null}async function readLocatedItem(item,options={}){const snapshot=await readLocatedItemSnapshot(item,options);if(snapshot.error!==null)throw snapshot.error;return{raw:snapshot.raw,document:snapshot.document}}async function readLocatedItemSnapshot(item,options={}){const bytes=await fs.readFile(item.itemPath);if(!isUtf8(bytes))throw new PmCliError("Item contains invalid UTF-8; preserve a binary backup before recovering it.",EXIT_CODE.CONFLICT,{code:"item_document_encoding_invalid",item_id:item.id,item_path:item.itemPath,byte_length:bytes.length,empty:!1});const raw=bytes.toString("utf8");await runActiveOnReadHooks({path:item.itemPath,scope:"project"});let document;try{document=parseItemDocument(raw,{format:item.item_format,requireSupportedFormat:!0,schema:options.schema,extensionFieldNames:resolveActiveExtensionFieldNames(options.extensionFieldNames),onWarning:warning=>appendWarning(options.warnings,warning)})}catch(error){if(error instanceof PmCliError&&error.code==="item_format_version_unsupported")throw new PmCliError(`Item ${item.id}: ${error.message}`,error.exitCode,{...error.context,item_id:item.id,item_path:item.itemPath});if(error instanceof PmCliError&&error.code==="item_document_invalid")return{raw,document:null,error:new PmCliError(`Cannot read ${item.id} at ${item.itemPath}${bytes.length===0?" (zero-length file)":""}: ${error.message}`,error.exitCode,{...error.context,item_id:item.id,item_path:item.itemPath,byte_length:bytes.length,empty:bytes.length===0,nextSteps:[`Run pm history ${item.id} --full, then pm restore ${item.id} <version> to recover a recorded state.`]})};throw error}return{raw,document,error:null}}async function listAllItemMetadata(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema){await assertReadableTrackerRoot(pmRoot);const documents=await listAllDocumentsCached(pmRoot,preferredFormat,typeToFolder,warnings,schema);return recordItemMetadataEnumeration(documents.length),documents.map(document=>document.metadata)}async function listAllItemMetadataLight(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema){await assertReadableTrackerRoot(pmRoot);const documents=await listAllDocumentsCachedLight(pmRoot,preferredFormat,typeToFolder,warnings,schema);return recordItemMetadataEnumeration(documents.length),documents.map(document=>document.metadata)}async function listAllItemMetadataWithBody(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema,options={}){await assertReadableTrackerRoot(pmRoot);const candidates=await listAllDocumentCandidatesCached(pmRoot,preferredFormat,typeToFolder,warnings,schema,{includeBody:!0,forceSourceScan:options.forceSourceScan});return recordItemMetadataEnumeration(candidates.length),candidates.map(candidate=>({...candidate.metadata,body:candidate.body}))}function createMutationGuardSdk(params){return{async get(id){const located=await locateItem(params.pmRoot,id,params.settings.id_prefix,params.settings.item_format,params.typeToFolder);if(!located)return null;const{document}=await readLocatedItem(located,{schema:params.settings.schema});return{item:document.metadata,body:document.body}},list:()=>listAllItemMetadata(params.pmRoot,params.settings.item_format,params.typeToFolder,void 0,params.settings.schema)}}async function listKnownItemIds(pmRoot,typeToFolder){const folders=new Set(Object.values(typeToFolder)),allIds=[];return await Promise.all([...folders].map(async folder=>{try{const entries=await fs.readdir(path.join(pmRoot,folder));for(const entry of entries)for(const ext of ITEM_FILE_EXTENSIONS)if(entry.toLowerCase().endsWith(ext)){allIds.push(entry.slice(0,-ext.length));break}}catch{}})),allIds}async function buildDidYouMeanSuggestions(pmRoot,badId,idPrefix,typeToFolder){const normalized=normalizeItemId(badId,idPrefix),ids=await listKnownItemIds(pmRoot,typeToFolder);if(ids.length===0)return[];const limit=Math.max(3,Math.floor(normalized.length/2));return ids.map(id=>({id,distance:levenshteinDistanceWithinLimit(id,normalized,limit)})).filter(entry=>entry.distance!==null).sort((left,right)=>left.distance-right.distance).slice(0,3).map(entry=>entry.id)}async function buildItemNotFoundError(pmRoot,badId,idPrefix,typeToFolder){const deleted=await buildDeletedItemError(pmRoot,badId,idPrefix);if(deleted)return deleted;const suggestions=await buildDidYouMeanSuggestions(pmRoot,badId,idPrefix,typeToFolder),nextSteps=["Confirm the active --path/PM_PATH scope, then retry with a valid id."];return suggestions.length>0&&nextSteps.unshift(`Did you mean one of: ${suggestions.join(", ")}?`),new PmCliError(`Item ${badId} not found`,EXIT_CODE.NOT_FOUND,{code:"item_not_found",id:badId,nextSteps})}function bypassesAssigneeConflict(op,bypassAssigneeConflict){return op==="claim"||bypassAssigneeConflict===!0&&(op==="comment_add"||op==="comment_edit"||op==="comment_delete"||op==="note_add"||op==="learning_add"||op==="release"||op==="update"||op==="update_ownership_bypass"||op==="update_audit")}async function prepareLockedItem(params){const typeToFolder=params.typeToFolder??resolveItemTypeRegistry(params.settings,getActiveExtensionRegistrations()).type_to_folder,located=await locateItem(params.pmRoot,params.id,params.settings.id_prefix,params.settings.item_format,typeToFolder);if(!located)throw await buildItemNotFoundError(params.pmRoot,params.id,params.settings.id_prefix,typeToFolder);const lease=await acquireLockLease(params.pmRoot,located.id,params.settings.locks.ttl_seconds,params.author,!!params.force,params.settings.governance.force_required_for_stale_lock,params.settings.locks.wait_ms,{waitPolicy:"progress"}),releaseLock=lease.release;try{const warnings=[],{raw:originalRaw,document}=await readLocatedItem(located,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames,warnings}),assigned=document.metadata.assignee?.trim(),assignedPrincipal=document.metadata.claim_principal?.trim()||assigned,callerPrincipal=resolveClaimPrincipal(params.author),governance=resolveGovernanceKnobs(params.settings);if(assigned&&assignedPrincipal!==callerPrincipal&&!params.force&&!bypassesAssigneeConflict(params.op,params.bypassAssigneeConflict)){if(governance.ownership_enforcement==="strict")throw new PmCliError(`Item ${located.id} is assigned to ${assigned}. Use --force to override.`,EXIT_CODE.CONFLICT);governance.ownership_enforcement==="warn"&&warnings.push(`ownership_warning:assignee_conflict:${located.id}:${assigned}`)}return{typeToFolder,located,originalRaw,document,warnings,releaseLock,lease}}catch(error){throw await releaseLock(),error}}async function commitLockedItemWrite(lease,located,originalRaw,commit){return lease.fence(async()=>{let currentRaw;try{currentRaw=await fs.readFile(located.itemPath,"utf8")}catch(error){if(!isFileMissingError(error))throw error;currentRaw=null}if(currentRaw!==originalRaw)throw new PmCliError(`Item ${located.id} changed after this mutation read it; refusing to overwrite the newer revision. Nothing was written.`,EXIT_CODE.CONFLICT,{code:"stale_revision",item_id:located.id,reason:currentRaw===null?"item_removed":"item_revision_changed",required:"Re-read the item and apply the mutation again; the newer stored revision was kept."});return commit()})}function resolveItemStoreWriteOverride(serviceWriteOverride,targetItemPath,serializedAfter){if(!serviceWriteOverride.handled||typeof serviceWriteOverride.result!="object"||serviceWriteOverride.result===null)return{effectiveTargetItemPath:targetItemPath,effectiveSerializedAfter:serializedAfter,skipItemWrite:!1};const overrideRecord=serviceWriteOverride.result;return{effectiveTargetItemPath:typeof overrideRecord.target_item_path=="string"&&overrideRecord.target_item_path.trim().length>0?overrideRecord.target_item_path:targetItemPath,effectiveSerializedAfter:typeof overrideRecord.contents=="string"?overrideRecord.contents:serializedAfter,skipItemWrite:overrideRecord.skip_write===!0}}async function resolveItemStoreDeleteOverride(payload){const override=await runActiveServiceOverride("item_store_delete",payload),record=override.handled&&typeof override.result=="object"&&override.result!==null?override.result:{};return{effectiveItemPath:typeof record.item_path=="string"&&record.item_path.trim().length>0?record.item_path:payload.item_path,skipDelete:record.skip_delete===!0,warnings:override.warnings}}async function rollbackMutatedItemWrite(params){if(!params.skipItemWrite){if(params.effectiveTargetItemPath!==params.originalItemPath){await writeFileAtomic(params.originalItemPath,params.originalRaw),await fs.rm(params.effectiveTargetItemPath,{force:!0});return}await writeFileAtomic(params.originalItemPath,params.originalRaw)}}async function mutateItemWithDeferredHistoryContext(params){normalizeHistoryOperationForWrite(params.op);const prepared=await prepareLockedItem({pmRoot:params.pmRoot,settings:params.settings,id:params.id,op:params.op,author:params.author,force:params.force,bypassAssigneeConflict:params.bypassAssigneeConflict,extensionFieldNames:params.extensionFieldNames,typeToFolder:params.typeToFolder}),{typeToFolder,located,originalRaw,document,warnings:parseWarnings,releaseLock,lease}=prepared;try{assertItemMutationPreconditions(params.pmRoot,document);const beforeDocument=canonicalDocument(document,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),mutableDocument=canonicalDocument(structuredClone(document),{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),mutation=await params.mutate(mutableDocument);if(params.skipNoop===!0&&mutation.changedFields.length===0)return{item:beforeDocument.metadata,body:beforeDocument.body,changedFields:[],warnings:[...parseWarnings,...mutation.warnings??[]]};const historyContext={...params.resolveHistoryContext?.(),...checkpointMutationHistoryContext(params.pmRoot,located.id),...itemMutationPreconditionHistoryContext(params.pmRoot,document)},requiredFormat=Math.max(requiredItemFormatVersion(beforeDocument.metadata),requiredItemFormatVersion(mutableDocument.metadata));assertProjectRuntimeFormatGuard(resolveWorkspaceRoot(params.pmRoot),requiredFormat),requiredFormat>effectiveItemFormatVersion(mutableDocument.metadata)&&(mutableDocument.metadata.pm_format_version=requiredFormat,mutation.changedFields.push("pm_format_version")),mutableDocument.metadata.updated_at=nowIso();const afterDocument=canonicalDocument(mutableDocument,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),workflowPolicy=await enforceWorkflowMutation({pmRoot:params.pmRoot,settings:params.settings,operation:params.op,author:params.author,before:beforeDocument,after:afterDocument});await runActiveBeforeMutationHooks({pm_root:params.pmRoot,operation:params.op,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields,sdk:createMutationGuardSdk({pmRoot:params.pmRoot,settings:params.settings,typeToFolder})});const historyPolicy=await enforceHistoryStreamPolicyForItem({pmRoot:params.pmRoot,settings:params.settings,itemId:located.id,commandLabel:params.op}),targetItemFormat="toon",serializedAfter=serializeItemDocument(afterDocument,{format:targetItemFormat,schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),targetItemPath=getItemPath(params.pmRoot,afterDocument.metadata.type,located.id,targetItemFormat,typeToFolder),historyPath=getHistoryPath(params.pmRoot,located.id),committed=await commitLockedItemWrite(lease,located,originalRaw,async()=>{const serviceWriteOverride=await runActiveServiceOverride("item_store_write",{op:params.op,pm_root:params.pmRoot,item_id:located.id,source_item_path:located.itemPath,target_item_path:targetItemPath,history_path:historyPath,item_format:targetItemFormat,before:beforeDocument,after:afterDocument,contents:serializedAfter}),{effectiveTargetItemPath:effectiveTargetItemPath2,effectiveSerializedAfter,skipItemWrite}=resolveItemStoreWriteOverride(serviceWriteOverride,targetItemPath,serializedAfter),releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);let derivedIndexWarnings2=[];try{skipItemWrite||await writeFileAtomic(effectiveTargetItemPath2,effectiveSerializedAfter),!skipItemWrite&&effectiveTargetItemPath2!==located.itemPath&&await fs.rm(located.itemPath);const entry=createHistoryEntry({nowIso:afterDocument.metadata.updated_at,author:params.author,op:params.op,before:beforeDocument,after:afterDocument,message:params.message,context:workflowPolicy.decisions.length===0?Object.keys(historyContext).length===0?void 0:historyContext:{...historyContext,workflow_policies:workflowPolicy.decisions}});try{await appendHistoryEntry(historyPath,entry)}catch(error){throw await rollbackMutatedItemWrite({skipItemWrite,effectiveTargetItemPath:effectiveTargetItemPath2,originalItemPath:located.itemPath,originalRaw}),error}skipItemWrite||(derivedIndexWarnings2=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder,schema:params.settings.schema,itemPath:effectiveTargetItemPath2,previousItemPath:located.itemPath,document:afterDocument}))}finally{await releaseDerivedIndexLock()}return{derivedIndexWarnings:derivedIndexWarnings2,effectiveTargetItemPath:effectiveTargetItemPath2,overrideWarnings:serviceWriteOverride.warnings}}),{derivedIndexWarnings,effectiveTargetItemPath}=committed;advanceItemMutationPreconditions(params.pmRoot,afterDocument);const hookWarnings=[...await runActiveOnWriteHooks({path:effectiveTargetItemPath,scope:"project",op:params.op,item_id:afterDocument.metadata.id,item_type:afterDocument.metadata.type,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields}),...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:`${params.op}:history`,item_id:afterDocument.metadata.id,item_type:afterDocument.metadata.type,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields})];return recordAfterCommandAffectedItem({id:afterDocument.metadata.id,op:params.op,item_type:afterDocument.metadata.type,previous_status:beforeDocument.metadata.status,status:afterDocument.metadata.status,previous:projectAfterCommandItemSnapshot(beforeDocument.metadata,mutation.changedFields),current:projectAfterCommandItemSnapshot(afterDocument.metadata,mutation.changedFields),changed_fields:mutation.changedFields}),{item:afterDocument.metadata,body:afterDocument.body,changedFields:mutation.changedFields,warnings:[...parseWarnings,...mutation.warnings??[],...workflowPolicy.warnings,...historyPolicy.warnings,...committed.overrideWarnings,...derivedIndexWarnings,...hookWarnings]}}finally{await releaseLock()}}async function mutateItemWithHistoryContext(params){const{historyContext,...mutationParams}=params;return mutateItemWithDeferredHistoryContext({...mutationParams,resolveHistoryContext:()=>historyContext})}async function mutateItemWithHistoryContextResolver(params){return mutateItemWithDeferredHistoryContext(params)}async function mutateItem(params){return mutateItemWithDeferredHistoryContext(params)}const itemStoreTestOnly={appendWarning,bypassesAssigneeConflict,buildDidYouMeanSuggestions,isErrno};async function deleteItem(params){const prepared=await prepareLockedItem({pmRoot:params.pmRoot,settings:params.settings,id:params.id,op:"delete",author:params.author,force:params.force}),{located,originalRaw,document,warnings:parseWarnings,releaseLock,lease}=prepared;try{assertItemMutationPreconditions(params.pmRoot,document);const extensionFieldNames=resolveActiveExtensionFieldNames(void 0),beforeDocument=canonicalDocument(document,{schema:params.settings.schema,extensionFieldNames}),workflowPolicy=await enforceWorkflowMutation({pmRoot:params.pmRoot,settings:params.settings,operation:"delete",author:params.author,before:beforeDocument,after:null,dryRun:params.dryRun});await runActiveBeforeMutationHooks({pm_root:params.pmRoot,operation:"delete",before:beforeDocument,after:null,changed_fields:["deleted"],sdk:createMutationGuardSdk({pmRoot:params.pmRoot,settings:params.settings,typeToFolder:prepared.typeToFolder})});const historyPolicy=await enforceHistoryStreamPolicyForItem({pmRoot:params.pmRoot,settings:params.settings,itemId:located.id,commandLabel:"delete"}),deletionTimestamp=nowIso(),tombstoneDocument=EMPTY_CANONICAL_DOCUMENT,historyEntry=createHistoryEntry({nowIso:deletionTimestamp,author:params.author,op:"delete",before:beforeDocument,after:tombstoneDocument,message:params.message,context:workflowPolicy.decisions.length===0?void 0:{workflow_policies:workflowPolicy.decisions}}),historyPath=getHistoryPath(params.pmRoot,located.id),runDeleteOverride=()=>resolveItemStoreDeleteOverride({op:"delete",pm_root:params.pmRoot,item_id:located.id,item_path:located.itemPath,history_path:historyPath,before:beforeDocument});if(params.dryRun===!0){const preview=await runDeleteOverride();return{item:beforeDocument.metadata,changedFields:["deleted"],targetPath:preview.effectiveItemPath,warnings:[...parseWarnings,...workflowPolicy.warnings,...historyPolicy.warnings,...preview.warnings]}}const committed=await commitLockedItemWrite(lease,located,originalRaw,async()=>{const{effectiveItemPath:effectiveItemPath2,skipDelete,warnings}=await runDeleteOverride(),releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);let derivedIndexWarnings2=[];try{skipDelete||await fs.rm(effectiveItemPath2);try{await appendHistoryEntry(historyPath,historyEntry)}catch(error){throw skipDelete||await writeFileAtomic(effectiveItemPath2,originalRaw),error}skipDelete||(derivedIndexWarnings2=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder:prepared.typeToFolder,schema:params.settings.schema,itemPath:effectiveItemPath2,document:null}))}finally{await releaseDerivedIndexLock()}return{derivedIndexWarnings:derivedIndexWarnings2,effectiveItemPath:effectiveItemPath2,overrideWarnings:warnings}}),{derivedIndexWarnings,effectiveItemPath}=committed,hookWarnings=[...await runActiveOnWriteHooks({path:effectiveItemPath,scope:"project",op:"delete",item_id:beforeDocument.metadata.id,item_type:beforeDocument.metadata.type,before:beforeDocument,after:tombstoneDocument,changed_fields:["deleted"]}),...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:"delete:history",item_id:beforeDocument.metadata.id,item_type:beforeDocument.metadata.type,before:beforeDocument,after:tombstoneDocument,changed_fields:["deleted"]})];return recordAfterCommandAffectedItem({id:beforeDocument.metadata.id,op:"delete",item_type:beforeDocument.metadata.type,previous_status:beforeDocument.metadata.status,previous:projectAfterCommandItemSnapshot(beforeDocument.metadata,Object.keys(beforeDocument.metadata)),changed_fields:["deleted"]}),{item:beforeDocument.metadata,changedFields:["deleted"],warnings:[...parseWarnings,...workflowPolicy.warnings,...historyPolicy.warnings,...committed.overrideWarnings,...derivedIndexWarnings,...hookWarnings]}}finally{await releaseLock()}}export{buildItemNotFoundError,createMutationGuardSdk,deleteItem,itemStoreTestOnly,listAllItemMetadata,listAllItemMetadataLight,listAllItemMetadataWithBody,locateItem,mutateItem,mutateItemWithHistoryContext,mutateItemWithHistoryContextResolver,readLocatedItem,readLocatedItemSnapshot};
1
+ (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="22232262-8057-5248-b462-1223d34a4570")}catch{}})();import fs from"node:fs/promises";import{buildDeletedItemError}from"../history/tombstone.js";import{normalizeHistoryOperationForWrite}from"../history/operation-contract.js";import{enforceWorkflowMutation}from"../policy/workflow-policy-store.js";import{recordItemMetadataEnumeration}from"./item-metadata-read-work.js";import{advanceItemMutationPreconditions,assertItemMutationPreconditions,itemMutationPreconditionHistoryContext}from"./item-mutation-precondition.js";import{checkpointMutationHistoryContext}from"../checkpoint/mutation-context.js";import path from"node:path";import{getActiveExtensionRegistrations,projectAfterCommandItemSnapshot,recordAfterCommandAffectedItem,runActiveOnReadHooks,runActiveBeforeMutationHooks,runActiveOnWriteHooks,runActiveServiceOverride}from"../extensions/index.js";import{collectRegisteredItemFieldNames}from"../extensions/item-fields.js";import{EMPTY_CANONICAL_DOCUMENT,EXIT_CODE,TYPE_TO_FOLDER}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{levenshteinDistanceWithinLimit}from"../shared/levenshtein.js";import{appendHistoryEntry,createHistoryEntry}from"../history/history.js";import{enforceHistoryStreamPolicyForItem}from"../history/history-stream-policy.js";import{canonicalDocument,parseItemDocument,serializeItemDocument}from"../item/item-format.js";import{resolveItemTypeRegistry}from"../item/type-registry.js";import{effectiveItemFormatVersion,requiredItemFormatVersion}from"../item/item-format-version.js";import{assertProjectRuntimeFormatGuard}from"../../sdk/environment/project-runtime-compatibility.js";import{acquireLockLease}from"../lock/lock.js";import{isFileMissingError,writeFileAtomic}from"../fs/fs-utils.js";import{isUtf8}from"node:buffer";import{normalizeItemId,normalizeRawItemId}from"../item/id.js";import{acquireItemMetadataDerivedIndexLock,listAllDocumentCandidatesCached,listAllDocumentsCached,listAllDocumentsCachedLight,refreshItemMetadataDerivedIndex}from"./item-metadata-cache.js";import{getHistoryPath,getItemPath,ITEM_FILE_EXTENSIONS,resolveWorkspaceRoot}from"./paths.js";import{resolveGovernanceKnobs}from"./settings.js";import{assertReadableTrackerRoot}from"./tracker-preflight.js";import{resolveClaimPrincipal}from"../shared/author.js";import{nowIso}from"../shared/time.js";async function fileExists(targetPath){try{return await fs.access(targetPath),!0}catch{return!1}}function isErrno(error,code){return typeof error=="object"&&error!==null&&"code"in error&&error.code===code}function appendWarning(warnings,warning){warnings&&(warnings.includes(warning)||warnings.push(warning))}function resolveActiveExtensionFieldNames(explicit){return explicit??collectRegisteredItemFieldNames(getActiveExtensionRegistrations())}function resolveItemFormatSearchOrder(preferredFormat){return preferredFormat==="toon"?["toon","json_markdown"]:preferredFormat==="json_markdown"?["json_markdown","toon"]:["toon","json_markdown"]}async function locateItem(pmRoot,rawId,idPrefix="pm-",preferredFormat,typeToFolder=TYPE_TO_FOLDER){const trimmedRawId=rawId.trim(),exactRawId=trimmedRawId.startsWith("#")?trimmedRawId.slice(1):trimmedRawId;if(exactRawId.length===0)return null;const normalizedId=normalizeItemId(rawId,idPrefix),rawNormalizedId=normalizeRawItemId(rawId),candidateIds=[...new Set([exactRawId,normalizedId,rawNormalizedId])].filter(candidateId=>candidateId.length>0),entries=Object.entries(typeToFolder),searchOrder=resolveItemFormatSearchOrder(preferredFormat);for(const candidateId of candidateIds){const matches=new Map;for(const[type]of entries)for(const itemFormat of searchOrder){const itemPath=getItemPath(pmRoot,type,candidateId,itemFormat,typeToFolder);await fileExists(itemPath)&&matches.set(itemPath,matches.get(itemPath)??{id:candidateId,type,itemPath,item_format:itemFormat})}if(matches.size>1){const paths=[...matches.keys()].map(itemPath=>path.relative(pmRoot,itemPath).split(path.sep).join("/")).sort();throw new PmCliError(`Item ${candidateId} has ambiguous identity across ${paths.join(", ")}. Preserve both documents and inspect pm ops validate --check-storage-integrity before resolving the collision.`,EXIT_CODE.CONFLICT,{code:"item_identity_ambiguous",item_id:candidateId,paths})}for(const match of matches.values())return match}return null}async function readLocatedItem(item,options={}){const snapshot=await readLocatedItemSnapshot(item,options);if(snapshot.error!==null)throw snapshot.error;return{raw:snapshot.raw,document:snapshot.document}}async function readLocatedItemSnapshot(item,options={}){const bytes=await fs.readFile(item.itemPath);if(!isUtf8(bytes))throw new PmCliError("Item contains invalid UTF-8; preserve a binary backup before recovering it.",EXIT_CODE.CONFLICT,{code:"item_document_encoding_invalid",item_id:item.id,item_path:item.itemPath,byte_length:bytes.length,empty:!1});const raw=bytes.toString("utf8");await runActiveOnReadHooks({path:item.itemPath,scope:"project"});let document;try{document=parseItemDocument(raw,{format:item.item_format,requireSupportedFormat:!0,schema:options.schema,extensionFieldNames:resolveActiveExtensionFieldNames(options.extensionFieldNames),onWarning:warning=>appendWarning(options.warnings,warning)})}catch(error){if(error instanceof PmCliError&&error.code==="item_format_version_unsupported")throw new PmCliError(`Item ${item.id}: ${error.message}`,error.exitCode,{...error.context,item_id:item.id,item_path:item.itemPath});if(error instanceof PmCliError&&error.code==="item_document_invalid")return{raw,document:null,error:new PmCliError(`Cannot read ${item.id} at ${item.itemPath}${bytes.length===0?" (zero-length file)":""}: ${error.message}`,error.exitCode,{...error.context,item_id:item.id,item_path:item.itemPath,byte_length:bytes.length,empty:bytes.length===0,nextSteps:[`Run pm history ${item.id} --full, then pm restore ${item.id} <version> to recover a recorded state.`]})};throw error}return{raw,document,error:null}}async function listAllItemMetadata(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema){await assertReadableTrackerRoot(pmRoot);const documents=await listAllDocumentsCached(pmRoot,preferredFormat,typeToFolder,warnings,schema);return recordItemMetadataEnumeration(documents.length),documents.map(document=>document.metadata)}async function listAllItemMetadataLight(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema){await assertReadableTrackerRoot(pmRoot);const documents=await listAllDocumentsCachedLight(pmRoot,preferredFormat,typeToFolder,warnings,schema);return recordItemMetadataEnumeration(documents.length),documents.map(document=>document.metadata)}async function listAllItemMetadataWithBody(pmRoot,preferredFormat,typeToFolder=TYPE_TO_FOLDER,warnings,schema,options={}){await assertReadableTrackerRoot(pmRoot);const candidates=await listAllDocumentCandidatesCached(pmRoot,preferredFormat,typeToFolder,warnings,schema,{includeBody:!0,forceSourceScan:options.forceSourceScan});return recordItemMetadataEnumeration(candidates.length),candidates.map(candidate=>({...candidate.metadata,body:candidate.body}))}function createMutationGuardSdk(params){return{async get(id){const located=await locateItem(params.pmRoot,id,params.settings.id_prefix,params.settings.item_format,params.typeToFolder);if(!located)return null;const{document}=await readLocatedItem(located,{schema:params.settings.schema});return{item:document.metadata,body:document.body}},list:()=>listAllItemMetadata(params.pmRoot,params.settings.item_format,params.typeToFolder,void 0,params.settings.schema)}}async function listKnownItemIds(pmRoot,typeToFolder){const folders=new Set(Object.values(typeToFolder)),allIds=[];return await Promise.all([...folders].map(async folder=>{try{const entries=await fs.readdir(path.join(pmRoot,folder));for(const entry of entries)for(const ext of ITEM_FILE_EXTENSIONS)if(entry.toLowerCase().endsWith(ext)){allIds.push(entry.slice(0,-ext.length));break}}catch{}})),allIds}async function buildDidYouMeanSuggestions(pmRoot,badId,idPrefix,typeToFolder){const normalized=normalizeItemId(badId,idPrefix),ids=await listKnownItemIds(pmRoot,typeToFolder);if(ids.length===0)return[];const limit=Math.max(3,Math.floor(normalized.length/2));return ids.map(id=>({id,distance:levenshteinDistanceWithinLimit(id,normalized,limit)})).filter(entry=>entry.distance!==null).sort((left,right)=>left.distance-right.distance).slice(0,3).map(entry=>entry.id)}async function buildItemNotFoundError(pmRoot,badId,idPrefix,typeToFolder){const deleted=await buildDeletedItemError(pmRoot,badId,idPrefix);if(deleted)return deleted;const suggestions=await buildDidYouMeanSuggestions(pmRoot,badId,idPrefix,typeToFolder),nextSteps=["Confirm the active --path/PM_PATH scope, then retry with a valid id."];return suggestions.length>0&&nextSteps.unshift(`Did you mean one of: ${suggestions.join(", ")}?`),new PmCliError(`Item ${badId} not found`,EXIT_CODE.NOT_FOUND,{code:"item_not_found",id:badId,nextSteps})}function bypassesAssigneeConflict(op,bypassAssigneeConflict){return op==="claim"||bypassAssigneeConflict===!0&&(op==="comment_add"||op==="comment_edit"||op==="comment_delete"||op==="note_add"||op==="learning_add"||op==="release"||op==="update"||op==="update_ownership_bypass"||op==="update_audit")}async function prepareLockedItem(params){const typeToFolder=params.typeToFolder??resolveItemTypeRegistry(params.settings,getActiveExtensionRegistrations()).type_to_folder,located=await locateItem(params.pmRoot,params.id,params.settings.id_prefix,params.settings.item_format,typeToFolder);if(!located)throw await buildItemNotFoundError(params.pmRoot,params.id,params.settings.id_prefix,typeToFolder);const lease=await acquireLockLease(params.pmRoot,located.id,params.settings.locks.ttl_seconds,params.author,!!params.force,params.settings.governance.force_required_for_stale_lock,params.settings.locks.wait_ms,{waitPolicy:"progress"}),releaseLock=lease.release;try{const warnings=[],{raw:originalRaw,document}=await readLocatedItem(located,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames,warnings}),assigned=document.metadata.assignee?.trim(),assignedPrincipal=document.metadata.claim_principal?.trim()||assigned,callerPrincipal=resolveClaimPrincipal(params.author),governance=resolveGovernanceKnobs(params.settings);if(assigned&&assignedPrincipal!==callerPrincipal&&!params.force&&!bypassesAssigneeConflict(params.op,params.bypassAssigneeConflict)){if(governance.ownership_enforcement==="strict")throw new PmCliError(`Item ${located.id} is assigned to ${assigned}. Use --force to override.`,EXIT_CODE.CONFLICT);governance.ownership_enforcement==="warn"&&warnings.push(`ownership_warning:assignee_conflict:${located.id}:${assigned}`)}return{typeToFolder,located,originalRaw,document,warnings,releaseLock,lease}}catch(error){throw await releaseLock(),error}}async function commitLockedItemWrite(lease,located,originalRaw,commit){return lease.fence(async()=>{let currentRaw;try{currentRaw=await fs.readFile(located.itemPath,"utf8")}catch(error){if(!isFileMissingError(error))throw error;currentRaw=null}if(currentRaw!==originalRaw)throw new PmCliError(`Item ${located.id} changed after this mutation read it; refusing to overwrite the newer revision. Nothing was written.`,EXIT_CODE.CONFLICT,{code:"stale_revision",item_id:located.id,reason:currentRaw===null?"item_removed":"item_revision_changed",required:"Re-read the item and apply the mutation again; the newer stored revision was kept."});return commit()})}function resolveItemStoreWriteOverride(serviceWriteOverride,targetItemPath,serializedAfter){if(!serviceWriteOverride.handled||typeof serviceWriteOverride.result!="object"||serviceWriteOverride.result===null)return{effectiveTargetItemPath:targetItemPath,effectiveSerializedAfter:serializedAfter,skipItemWrite:!1};const overrideRecord=serviceWriteOverride.result;return{effectiveTargetItemPath:typeof overrideRecord.target_item_path=="string"&&overrideRecord.target_item_path.trim().length>0?overrideRecord.target_item_path:targetItemPath,effectiveSerializedAfter:typeof overrideRecord.contents=="string"?overrideRecord.contents:serializedAfter,skipItemWrite:overrideRecord.skip_write===!0}}async function resolveItemStoreDeleteOverride(payload){const override=await runActiveServiceOverride("item_store_delete",payload),record=override.handled&&typeof override.result=="object"&&override.result!==null?override.result:{};return{effectiveItemPath:typeof record.item_path=="string"&&record.item_path.trim().length>0?record.item_path:payload.item_path,skipDelete:record.skip_delete===!0,warnings:override.warnings}}async function rollbackMutatedItemWrite(params){if(!params.skipItemWrite){if(params.effectiveTargetItemPath!==params.originalItemPath){await writeFileAtomic(params.originalItemPath,params.originalRaw),await fs.rm(params.effectiveTargetItemPath,{force:!0});return}await writeFileAtomic(params.originalItemPath,params.originalRaw)}}async function mutateItemWithDeferredHistoryContext(params){normalizeHistoryOperationForWrite(params.op);const prepared=await prepareLockedItem({pmRoot:params.pmRoot,settings:params.settings,id:params.id,op:params.op,author:params.author,force:params.force,bypassAssigneeConflict:params.bypassAssigneeConflict,extensionFieldNames:params.extensionFieldNames,typeToFolder:params.typeToFolder}),{typeToFolder,located,originalRaw,document,warnings:parseWarnings,releaseLock,lease}=prepared;try{assertItemMutationPreconditions(params.pmRoot,document,located.id);const beforeDocument=canonicalDocument(document,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),mutableDocument=canonicalDocument(structuredClone(document),{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),mutation=await params.mutate(mutableDocument);if(params.skipNoop===!0&&mutation.changedFields.length===0)return{item:beforeDocument.metadata,body:beforeDocument.body,changedFields:[],warnings:[...parseWarnings,...mutation.warnings??[]]};const historyContext={...params.resolveHistoryContext?.(),...checkpointMutationHistoryContext(params.pmRoot,located.id),...itemMutationPreconditionHistoryContext(params.pmRoot,[located.id,document.metadata.id])},requiredFormat=Math.max(requiredItemFormatVersion(beforeDocument.metadata),requiredItemFormatVersion(mutableDocument.metadata));assertProjectRuntimeFormatGuard(resolveWorkspaceRoot(params.pmRoot),requiredFormat),requiredFormat>effectiveItemFormatVersion(mutableDocument.metadata)&&(mutableDocument.metadata.pm_format_version=requiredFormat,mutation.changedFields.push("pm_format_version")),mutableDocument.metadata.updated_at=nowIso();const afterDocument=canonicalDocument(mutableDocument,{schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),workflowPolicy=await enforceWorkflowMutation({pmRoot:params.pmRoot,settings:params.settings,operation:params.op,author:params.author,before:beforeDocument,after:afterDocument});await runActiveBeforeMutationHooks({pm_root:params.pmRoot,operation:params.op,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields,sdk:createMutationGuardSdk({pmRoot:params.pmRoot,settings:params.settings,typeToFolder})});const historyPolicy=await enforceHistoryStreamPolicyForItem({pmRoot:params.pmRoot,settings:params.settings,itemId:located.id,commandLabel:params.op}),targetItemFormat="toon",serializedAfter=serializeItemDocument(afterDocument,{format:targetItemFormat,schema:params.settings.schema,extensionFieldNames:params.extensionFieldNames}),targetItemPath=getItemPath(params.pmRoot,afterDocument.metadata.type,located.id,targetItemFormat,typeToFolder),historyPath=getHistoryPath(params.pmRoot,located.id),committed=await commitLockedItemWrite(lease,located,originalRaw,async()=>{const serviceWriteOverride=await runActiveServiceOverride("item_store_write",{op:params.op,pm_root:params.pmRoot,item_id:located.id,source_item_path:located.itemPath,target_item_path:targetItemPath,history_path:historyPath,item_format:targetItemFormat,before:beforeDocument,after:afterDocument,contents:serializedAfter}),{effectiveTargetItemPath:effectiveTargetItemPath2,effectiveSerializedAfter,skipItemWrite}=resolveItemStoreWriteOverride(serviceWriteOverride,targetItemPath,serializedAfter),releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);let derivedIndexWarnings2=[];try{skipItemWrite||await writeFileAtomic(effectiveTargetItemPath2,effectiveSerializedAfter),!skipItemWrite&&effectiveTargetItemPath2!==located.itemPath&&await fs.rm(located.itemPath);const entry=createHistoryEntry({nowIso:afterDocument.metadata.updated_at,author:params.author,op:params.op,before:beforeDocument,after:afterDocument,message:params.message,context:workflowPolicy.decisions.length===0?Object.keys(historyContext).length===0?void 0:historyContext:{...historyContext,workflow_policies:workflowPolicy.decisions}});try{await appendHistoryEntry(historyPath,entry)}catch(error){throw await rollbackMutatedItemWrite({skipItemWrite,effectiveTargetItemPath:effectiveTargetItemPath2,originalItemPath:located.itemPath,originalRaw}),error}skipItemWrite||(derivedIndexWarnings2=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder,schema:params.settings.schema,itemPath:effectiveTargetItemPath2,previousItemPath:located.itemPath,document:afterDocument}))}finally{await releaseDerivedIndexLock()}return{derivedIndexWarnings:derivedIndexWarnings2,effectiveTargetItemPath:effectiveTargetItemPath2,overrideWarnings:serviceWriteOverride.warnings}}),{derivedIndexWarnings,effectiveTargetItemPath}=committed;advanceItemMutationPreconditions(params.pmRoot,afterDocument,located.id);const hookWarnings=[...await runActiveOnWriteHooks({path:effectiveTargetItemPath,scope:"project",op:params.op,item_id:afterDocument.metadata.id,item_type:afterDocument.metadata.type,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields}),...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:`${params.op}:history`,item_id:afterDocument.metadata.id,item_type:afterDocument.metadata.type,before:beforeDocument,after:afterDocument,changed_fields:mutation.changedFields})];return recordAfterCommandAffectedItem({id:afterDocument.metadata.id,op:params.op,item_type:afterDocument.metadata.type,previous_status:beforeDocument.metadata.status,status:afterDocument.metadata.status,previous:projectAfterCommandItemSnapshot(beforeDocument.metadata,mutation.changedFields),current:projectAfterCommandItemSnapshot(afterDocument.metadata,mutation.changedFields),changed_fields:mutation.changedFields}),{item:afterDocument.metadata,body:afterDocument.body,changedFields:mutation.changedFields,warnings:[...parseWarnings,...mutation.warnings??[],...workflowPolicy.warnings,...historyPolicy.warnings,...committed.overrideWarnings,...derivedIndexWarnings,...hookWarnings]}}finally{await releaseLock()}}async function mutateItemWithHistoryContext(params){const{historyContext,...mutationParams}=params;return mutateItemWithDeferredHistoryContext({...mutationParams,resolveHistoryContext:()=>historyContext})}async function mutateItemWithHistoryContextResolver(params){return mutateItemWithDeferredHistoryContext(params)}async function mutateItem(params){return mutateItemWithDeferredHistoryContext(params)}const itemStoreTestOnly={appendWarning,bypassesAssigneeConflict,buildDidYouMeanSuggestions,isErrno};async function deleteItem(params){const prepared=await prepareLockedItem({pmRoot:params.pmRoot,settings:params.settings,id:params.id,op:"delete",author:params.author,force:params.force}),{located,originalRaw,document,warnings:parseWarnings,releaseLock,lease}=prepared;try{assertItemMutationPreconditions(params.pmRoot,document,located.id);const extensionFieldNames=resolveActiveExtensionFieldNames(void 0),beforeDocument=canonicalDocument(document,{schema:params.settings.schema,extensionFieldNames}),workflowPolicy=await enforceWorkflowMutation({pmRoot:params.pmRoot,settings:params.settings,operation:"delete",author:params.author,before:beforeDocument,after:null,dryRun:params.dryRun});await runActiveBeforeMutationHooks({pm_root:params.pmRoot,operation:"delete",before:beforeDocument,after:null,changed_fields:["deleted"],sdk:createMutationGuardSdk({pmRoot:params.pmRoot,settings:params.settings,typeToFolder:prepared.typeToFolder})});const historyPolicy=await enforceHistoryStreamPolicyForItem({pmRoot:params.pmRoot,settings:params.settings,itemId:located.id,commandLabel:"delete"}),deletionTimestamp=nowIso(),tombstoneDocument=EMPTY_CANONICAL_DOCUMENT,historyEntry=createHistoryEntry({nowIso:deletionTimestamp,author:params.author,op:"delete",before:beforeDocument,after:tombstoneDocument,message:params.message,context:workflowPolicy.decisions.length===0?void 0:{workflow_policies:workflowPolicy.decisions}}),historyPath=getHistoryPath(params.pmRoot,located.id),runDeleteOverride=()=>resolveItemStoreDeleteOverride({op:"delete",pm_root:params.pmRoot,item_id:located.id,item_path:located.itemPath,history_path:historyPath,before:beforeDocument});if(params.dryRun===!0){const preview=await runDeleteOverride();return{item:beforeDocument.metadata,changedFields:["deleted"],targetPath:preview.effectiveItemPath,warnings:[...parseWarnings,...workflowPolicy.warnings,...historyPolicy.warnings,...preview.warnings]}}const committed=await commitLockedItemWrite(lease,located,originalRaw,async()=>{const{effectiveItemPath:effectiveItemPath2,skipDelete,warnings}=await runDeleteOverride(),releaseDerivedIndexLock=await acquireItemMetadataDerivedIndexLock(params.pmRoot,params.author);let derivedIndexWarnings2=[];try{skipDelete||await fs.rm(effectiveItemPath2);try{await appendHistoryEntry(historyPath,historyEntry)}catch(error){throw skipDelete||await writeFileAtomic(effectiveItemPath2,originalRaw),error}skipDelete||(derivedIndexWarnings2=await refreshItemMetadataDerivedIndex({pmRoot:params.pmRoot,preferredFormat:params.settings.item_format,typeToFolder:prepared.typeToFolder,schema:params.settings.schema,itemPath:effectiveItemPath2,document:null}))}finally{await releaseDerivedIndexLock()}return{derivedIndexWarnings:derivedIndexWarnings2,effectiveItemPath:effectiveItemPath2,overrideWarnings:warnings}}),{derivedIndexWarnings,effectiveItemPath}=committed;advanceItemMutationPreconditions(params.pmRoot,tombstoneDocument,located.id,[document.metadata.id]);const hookWarnings=[...await runActiveOnWriteHooks({path:effectiveItemPath,scope:"project",op:"delete",item_id:beforeDocument.metadata.id,item_type:beforeDocument.metadata.type,before:beforeDocument,after:tombstoneDocument,changed_fields:["deleted"]}),...await runActiveOnWriteHooks({path:historyPath,scope:"project",op:"delete:history",item_id:beforeDocument.metadata.id,item_type:beforeDocument.metadata.type,before:beforeDocument,after:tombstoneDocument,changed_fields:["deleted"]})];return recordAfterCommandAffectedItem({id:beforeDocument.metadata.id,op:"delete",item_type:beforeDocument.metadata.type,previous_status:beforeDocument.metadata.status,previous:projectAfterCommandItemSnapshot(beforeDocument.metadata,Object.keys(beforeDocument.metadata)),changed_fields:["deleted"]}),{item:beforeDocument.metadata,changedFields:["deleted"],warnings:[...parseWarnings,...workflowPolicy.warnings,...historyPolicy.warnings,...committed.overrideWarnings,...derivedIndexWarnings,...hookWarnings]}}finally{await releaseLock()}}export{buildItemNotFoundError,createMutationGuardSdk,deleteItem,itemStoreTestOnly,listAllItemMetadata,listAllItemMetadataLight,listAllItemMetadataWithBody,locateItem,mutateItem,mutateItemWithHistoryContext,mutateItemWithHistoryContextResolver,readLocatedItem,readLocatedItemSnapshot};
2
2
  //# sourceMappingURL=item-store.js.map
@@ -1,2 +1,2 @@
1
- (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c7f9d249-e2c2-5edd-afbd-b14ac1c12e81")}catch{}})();import{GOVERNANCE_PRESET_VALUES,RUNTIME_FIELD_COMMAND_VALUES,RUNTIME_FIELD_TYPE_VALUES,RUNTIME_STATUS_ROLE_VALUES,RUNTIME_UNKNOWN_FIELD_POLICY_VALUES}from"../../types.js";const FAIL={ok:!1,path:[]};function failAt(segment,failure){return{ok:!1,path:[segment,...failure.path]}}const vString=input=>typeof input=="string"?{ok:!0,value:input}:FAIL,vBoolean=input=>typeof input=="boolean"?{ok:!0,value:input}:FAIL;function vNumber(options={}){return input=>typeof input!="number"||!Number.isFinite(input)||options.int&&(!Number.isInteger(input)||!Number.isSafeInteger(input))||options.positive&&input<=0||typeof options.min=="number"&&input<options.min||typeof options.max=="number"&&input>options.max?FAIL:{ok:!0,value:input}}function vLiteral(...allowed){return input=>typeof input=="string"&&allowed.includes(input)?{ok:!0,value:input}:FAIL}function vArray(item,maxLength){return input=>{if(!Array.isArray(input)||maxLength!==void 0&&input.length>maxLength)return FAIL;const value=[];for(const[index,element]of input.entries()){const result=item(element);if(!result.ok)return failAt(String(index),result);value.push(result.value)}return{ok:!0,value}}}function vBoundedNormalizedString(maxLength,pattern){return input=>typeof input=="string"&&input.length>0&&input.length<=maxLength&&input===input.trim()&&(pattern===void 0||pattern.test(input))?{ok:!0,value:input}:FAIL}function vOptional(inner){return input=>input===void 0?{ok:!0,value:void 0}:inner(input)}function vRecordOf(valueCheck){return input=>{if(typeof input!="object"||input===null||Array.isArray(input))return FAIL;const value={};for(const[key,raw]of Object.entries(input)){const result=valueCheck(raw);if(!result.ok)return failAt(key,result);value[key]=result.value}return{ok:!0,value}}}function vObject(shape){return input=>{if(typeof input!="object"||input===null||Array.isArray(input))return FAIL;const record=input,value={};for(const[key,check]of Object.entries(shape)){const result=check(record[key]);if(!result.ok)return failAt(key,result);result.value!==void 0&&(value[key]=result.value)}return{ok:!0,value}}}const itemTypeOption=vObject({key:vString,values:vArray(vString),required:vOptional(vBoolean),aliases:vOptional(vArray(vString)),description:vOptional(vString)}),itemTypeCommandOptionPolicy=vObject({command:vLiteral("create","update"),option:vString,required:vOptional(vBoolean),visible:vOptional(vBoolean),enabled:vOptional(vBoolean)}),itemTypeDefinition=vObject({name:vString,description:vOptional(vString),default_status:vOptional(vString),execution_role:vOptional(vLiteral("agent","human","gate")),folder:vOptional(vString),aliases:vOptional(vArray(vString)),required_create_fields:vOptional(vArray(vString)),required_create_repeatables:vOptional(vArray(vString)),options:vOptional(vArray(itemTypeOption)),command_option_policies:vOptional(vArray(itemTypeCommandOptionPolicy))}),runtimeStatusDefinition=vObject({id:vString,aliases:vOptional(vArray(vString)),roles:vOptional(vArray(vLiteral(...RUNTIME_STATUS_ROLE_VALUES))),description:vOptional(vString),order:vOptional(vNumber())}),runtimeFieldDefinition=vObject({key:vString,metadata_key:vOptional(vString),front_matter_key:vOptional(vString),cli_flag:vOptional(vString),cli_aliases:vOptional(vArray(vString)),description:vOptional(vString),type:vOptional(vLiteral(...RUNTIME_FIELD_TYPE_VALUES)),commands:vOptional(vArray(vLiteral(...RUNTIME_FIELD_COMMAND_VALUES))),repeatable:vOptional(vBoolean),required:vOptional(vBoolean),required_on_create:vOptional(vBoolean),required_types:vOptional(vArray(vString)),allow_unset:vOptional(vBoolean)}),statusTransitionPair=input=>{if(!Array.isArray(input)||input.length!==2)return FAIL;const[from,to]=input;return typeof from!="string"||typeof to!="string"?FAIL:{ok:!0,value:[from,to]}},typeWorkflowDefinition=vObject({type:vString,allowed_transitions:vArray(statusTransitionPair)}),runtimeSchemaSettings=vOptional(vObject({version:vOptional(vNumber({int:!0})),files:vOptional(vObject({types:vOptional(vString),statuses:vOptional(vString),fields:vOptional(vString),workflows:vOptional(vString)})),statuses:vOptional(vArray(runtimeStatusDefinition)),fields:vOptional(vArray(runtimeFieldDefinition)),workflow:vOptional(vObject({draft_status:vOptional(vString),open_status:vOptional(vString),in_progress_status:vOptional(vString),blocked_status:vOptional(vString),close_status:vOptional(vString),canceled_status:vOptional(vString)})),type_workflows:vOptional(vArray(typeWorkflowDefinition)),unknown_field_policy:vOptional(vLiteral(...RUNTIME_UNKNOWN_FIELD_POLICY_VALUES))})),governanceSettings=vOptional(vObject({preset:vOptional(vLiteral(...GOVERNANCE_PRESET_VALUES)),ownership_enforcement:vOptional(vLiteral("none","warn","strict")),create_mode_default:vOptional(vLiteral("progressive","strict")),close_validation_default:vOptional(vLiteral("off","warn","strict")),require_close_reason:vOptional(vBoolean),parent_reference:vOptional(vLiteral("warn","strict_error")),metadata_profile:vOptional(vLiteral("core","strict","custom")),force_required_for_stale_lock:vOptional(vBoolean),create_default_type:vOptional(vString),workflow_enforcement:vOptional(vLiteral("off","warn","strict")),duplicate_detection_mode:vOptional(vLiteral("off","advisory","strict")),duplicate_detection_threshold:vOptional(vNumber({min:0,max:1})),duplicate_detection_limit:vOptional(vNumber({int:!0,min:0,max:20}))})),extensionPolicyOverride=vObject({name:vString,disabled:vOptional(vBoolean),require_trusted:vOptional(vBoolean),require_provenance:vOptional(vBoolean),sandbox_profile:vOptional(vLiteral("none","restricted","strict")),allowed_capabilities:vOptional(vArray(vString)),blocked_capabilities:vOptional(vArray(vString)),allowed_surfaces:vOptional(vArray(vString)),blocked_surfaces:vOptional(vArray(vString)),allowed_commands:vOptional(vArray(vString)),blocked_commands:vOptional(vArray(vString)),allowed_actions:vOptional(vArray(vString)),blocked_actions:vOptional(vArray(vString)),allowed_services:vOptional(vArray(vString)),blocked_services:vOptional(vArray(vString))}),pmMaxVersionExceededModeLiteral=vLiteral("block","warn"),pmMaxVersionExceededMode=input=>typeof input=="string"?pmMaxVersionExceededModeLiteral(input):vObject({global:vOptional(pmMaxVersionExceededModeLiteral),project:vOptional(pmMaxVersionExceededModeLiteral)})(input),extensionPolicy=vOptional(vObject({mode:vOptional(vLiteral("off","warn","enforce")),trust_mode:vOptional(vLiteral("off","warn","enforce")),pm_max_version_exceeded_mode:vOptional(pmMaxVersionExceededMode),require_provenance:vOptional(vBoolean),trusted_extensions:vOptional(vArray(vString)),default_sandbox_profile:vOptional(vLiteral("none","restricted","strict")),allowed_extensions:vOptional(vArray(vString)),blocked_extensions:vOptional(vArray(vString)),allowed_capabilities:vOptional(vArray(vString)),blocked_capabilities:vOptional(vArray(vString)),allowed_surfaces:vOptional(vArray(vString)),blocked_surfaces:vOptional(vArray(vString)),allowed_commands:vOptional(vArray(vString)),blocked_commands:vOptional(vArray(vString)),allowed_actions:vOptional(vArray(vString)),blocked_actions:vOptional(vArray(vString)),allowed_services:vOptional(vArray(vString)),blocked_services:vOptional(vArray(vString)),extension_overrides:vOptional(vArray(extensionPolicyOverride))})),harnessSignalLiteral=vBoundedNormalizedString(128),harnessSignalDescriptor=vObject({harness:vBoundedNormalizedString(128,/^[a-z0-9]+(?:-[a-z0-9]+)*$/u),environment_keys:vOptional(vArray(harnessSignalLiteral,64)),model_environment_keys:vOptional(vArray(harnessSignalLiteral,64)),session_environment_keys:vOptional(vArray(harnessSignalLiteral,64)),provenance_environment_keys:vOptional(vRecordOf(vArray(harnessSignalLiteral,64))),provenance_resolvers:vOptional(vRecordOf(vLiteral("ai_agent_version","claude_session_file"))),provenance_unavailable_dimensions:vOptional(vArray(harnessSignalLiteral,64)),argv_markers:vOptional(vArray(harnessSignalLiteral,64)),client_names:vOptional(vArray(harnessSignalLiteral,64))}),SETTINGS_SHAPE={version:vNumber({int:!0}),id_prefix:vString,ids:vOptional(vObject({token_length:vOptional(vNumber({int:!0,min:4,max:12}))})),author_default:vString,agent_identity:vOptional(vObject({probes_enabled:vOptional(vBoolean),identity_vocabulary:vOptional(vObject({version:vNumber({int:!0,positive:!0}),aliases:vRecordOf(vBoundedNormalizedString(128,/^[a-z0-9]+(?:-[a-z0-9]+)*$/u))})),harness_signals:vArray(harnessSignalDescriptor)})),mutation_guard:vOptional(vObject({require_attributed_author:vOptional(vBoolean),secret_guard:vOptional(vLiteral("off","advise","block")),stale_in_progress_hours:vOptional(vNumber({int:!0,positive:!0}))})),item_format:vOptional(vLiteral("toon","json_markdown")),locks:vObject({ttl_seconds:vNumber({int:!0}),wait_ms:vOptional(vNumber({int:!0,min:0}))}),checkpoints:vOptional(vObject({retention_days:vOptional(vNumber({int:!0,positive:!0}))})),output:vObject({default_format:vLiteral("toon","json")}),ux:vOptional(vObject({deprecation_hints:vOptional(vBoolean)})),history:vOptional(vObject({missing_stream:vLiteral("auto_create","strict_error"),compact_policy:vOptional(vObject({enabled:vOptional(vBoolean),max_entries:vOptional(vNumber({int:!0,positive:!0})),trigger:vOptional(vLiteral("health_warn","auto"))}))})),validation:vOptional(vObject({sprint_release_format:vLiteral("warn","strict_error"),parent_reference:vOptional(vLiteral("warn","strict_error")),metadata_profile:vOptional(vLiteral("core","strict","custom")),metadata_required_fields:vOptional(vArray(vString)),lifecycle_stale_blocker_reason_patterns:vOptional(vArray(vString)),lifecycle_closure_like_blocked_reason_patterns:vOptional(vArray(vString)),lifecycle_closure_like_resolution_patterns:vOptional(vArray(vString)),lifecycle_closure_like_actual_result_patterns:vOptional(vArray(vString)),estimate_defaults_by_type:vOptional(vRecordOf(vNumber({int:!0,positive:!0})))})),governance:governanceSettings,workflow:vOptional(vObject({definition_of_done:vArray(vString)})),testing:vOptional(vObject({record_results_to_items:vBoolean,allow_untrusted_linked_tests:vOptional(vBoolean)})),telemetry:vOptional(vObject({enabled:vBoolean,first_run_prompt_completed:vOptional(vBoolean),capture_level:vOptional(vLiteral("minimal","redacted","max")),endpoint:vOptional(vString),installation_id:vOptional(vString),retention_days:vOptional(vNumber({int:!0,positive:!0}))})),agent_guidance:vOptional(vObject({prompt_completed:vOptional(vBoolean),declined:vOptional(vBoolean),declined_at:vOptional(vString),template_version:vOptional(vNumber({int:!0,positive:!0})),last_checked_files:vOptional(vArray(vString))})),item_types:vOptional(vObject({definitions:vArray(itemTypeDefinition)})),schema:runtimeSchemaSettings,context:vOptional(vObject({default_depth:vOptional(vLiteral("brief","standard","deep")),activity_limit:vOptional(vNumber({int:!0,positive:!0})),stale_threshold_days:vOptional(vNumber({int:!0,positive:!0})),next_ranking_policy:vOptional(vLiteral("priority_floor","weighted")),sections:vOptional(vObject({hierarchy:vOptional(vBoolean),activity:vOptional(vBoolean),progress:vOptional(vBoolean),recently_created:vOptional(vBoolean),unparented:vOptional(vBoolean),blockers:vOptional(vBoolean),files:vOptional(vBoolean),workload:vOptional(vBoolean),staleness:vOptional(vBoolean),tests:vOptional(vBoolean)}))})),extensions:vObject({enabled:vArray(vString),disabled:vArray(vString),policy:extensionPolicy}),search:vObject({score_threshold:vNumber(),hybrid_semantic_weight:vOptional(vNumber()),max_results:vNumber({int:!0}),embedding_model:vString,embedding_corpus_max_characters:vOptional(vNumber()),embedding_batch_size:vNumber({int:!0}),embedding_timeout_ms:vOptional(vNumber({int:!0})),scanner_max_batch_retries:vNumber({int:!0}),provider:vOptional(vString),default_mode:vOptional(vLiteral("auto","keyword","semantic","hybrid")),corpus_fields:vOptional(vArray(vString)),mutation_refresh_policy:vOptional(vLiteral("cache_only","semantic_configured","semantic_auto")),query_expansion:vOptional(vObject({enabled:vOptional(vBoolean),provider:vOptional(vString)})),rerank:vOptional(vObject({enabled:vOptional(vBoolean),model:vOptional(vString),top_k:vOptional(vNumber({int:!0,positive:!0}))})),bm25:vOptional(vObject({k1:vOptional(vNumber()),b:vOptional(vNumber())}))}),providers:vObject({openai:vObject({base_url:vString,api_key:vString,model:vString}),ollama:vObject({base_url:vString,model:vString})}),vector_store:vObject({adapter:vOptional(vString),collection_name:vOptional(vString),qdrant:vObject({url:vString,api_key:vString}),lancedb:vObject({path:vString})})},settingsCheck=vObject(SETTINGS_SHAPE),CORE_SETTINGS_SECTION_KEYS=Object.freeze(Object.keys(SETTINGS_SHAPE));function validateSettings(raw){const result=settingsCheck(raw);return result.ok?{success:!0,data:result.value}:{success:!1,path:result.path.join(".")}}export{CORE_SETTINGS_SECTION_KEYS,validateSettings};
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]="33d6dc97-17d3-5db3-ab0d-6857be0e5827")}catch{}})();import{GOVERNANCE_PRESET_VALUES,RUNTIME_FIELD_COMMAND_VALUES,RUNTIME_FIELD_TYPE_VALUES,RUNTIME_STATUS_ROLE_VALUES,RUNTIME_UNKNOWN_FIELD_POLICY_VALUES}from"../../types.js";const FAIL={ok:!1,path:[]};function failAt(segment,failure){return{ok:!1,path:[segment,...failure.path]}}const vString=input=>typeof input=="string"?{ok:!0,value:input}:FAIL,vBoolean=input=>typeof input=="boolean"?{ok:!0,value:input}:FAIL;function vNumber(options={}){return input=>typeof input!="number"||!Number.isFinite(input)||options.int&&(!Number.isInteger(input)||!Number.isSafeInteger(input))||options.positive&&input<=0||typeof options.min=="number"&&input<options.min||typeof options.max=="number"&&input>options.max?FAIL:{ok:!0,value:input}}function vLiteral(...allowed){return input=>typeof input=="string"&&allowed.includes(input)?{ok:!0,value:input}:FAIL}function vArray(item,maxLength){return input=>{if(!Array.isArray(input)||maxLength!==void 0&&input.length>maxLength)return FAIL;const value=[];for(const[index,element]of input.entries()){const result=item(element);if(!result.ok)return failAt(String(index),result);value.push(result.value)}return{ok:!0,value}}}function vBoundedNormalizedString(maxLength,pattern){return input=>typeof input=="string"&&input.length>0&&input.length<=maxLength&&input===input.trim()&&(pattern===void 0||pattern.test(input))?{ok:!0,value:input}:FAIL}function vOptional(inner){return input=>input===void 0?{ok:!0,value:void 0}:inner(input)}function vRecordOf(valueCheck){return input=>{if(typeof input!="object"||input===null||Array.isArray(input))return FAIL;const value={};for(const[key,raw]of Object.entries(input)){const result=valueCheck(raw);if(!result.ok)return failAt(key,result);value[key]=result.value}return{ok:!0,value}}}function vObject(shape){return input=>{if(typeof input!="object"||input===null||Array.isArray(input))return FAIL;const record=input,value={};for(const[key,check]of Object.entries(shape)){const result=check(record[key]);if(!result.ok)return failAt(key,result);result.value!==void 0&&(value[key]=result.value)}return{ok:!0,value}}}const itemTypeOption=vObject({key:vString,values:vArray(vString),required:vOptional(vBoolean),aliases:vOptional(vArray(vString)),description:vOptional(vString)}),itemTypeCommandOptionPolicy=vObject({command:vLiteral("create","update"),option:vString,required:vOptional(vBoolean),visible:vOptional(vBoolean),enabled:vOptional(vBoolean)}),itemTypeDefinition=vObject({name:vString,description:vOptional(vString),default_status:vOptional(vString),execution_role:vOptional(vLiteral("agent","human","gate")),folder:vOptional(vString),aliases:vOptional(vArray(vString)),required_create_fields:vOptional(vArray(vString)),required_create_repeatables:vOptional(vArray(vString)),options:vOptional(vArray(itemTypeOption)),command_option_policies:vOptional(vArray(itemTypeCommandOptionPolicy))}),runtimeStatusDefinition=vObject({id:vString,aliases:vOptional(vArray(vString)),roles:vOptional(vArray(vLiteral(...RUNTIME_STATUS_ROLE_VALUES))),description:vOptional(vString),order:vOptional(vNumber())}),runtimeFieldDefinition=vObject({key:vString,metadata_key:vOptional(vString),front_matter_key:vOptional(vString),cli_flag:vOptional(vString),cli_aliases:vOptional(vArray(vString)),description:vOptional(vString),type:vOptional(vLiteral(...RUNTIME_FIELD_TYPE_VALUES)),commands:vOptional(vArray(vLiteral(...RUNTIME_FIELD_COMMAND_VALUES))),repeatable:vOptional(vBoolean),required:vOptional(vBoolean),required_on_create:vOptional(vBoolean),required_types:vOptional(vArray(vString)),allow_unset:vOptional(vBoolean)}),statusTransitionPair=input=>{if(!Array.isArray(input)||input.length!==2)return FAIL;const[from,to]=input;return typeof from!="string"||typeof to!="string"?FAIL:{ok:!0,value:[from,to]}},typeWorkflowDefinition=vObject({type:vString,allowed_transitions:vArray(statusTransitionPair)}),runtimeSchemaSettings=vOptional(vObject({version:vOptional(vNumber({int:!0})),files:vOptional(vObject({types:vOptional(vString),statuses:vOptional(vString),fields:vOptional(vString),workflows:vOptional(vString)})),statuses:vOptional(vArray(runtimeStatusDefinition)),fields:vOptional(vArray(runtimeFieldDefinition)),workflow:vOptional(vObject({draft_status:vOptional(vString),open_status:vOptional(vString),in_progress_status:vOptional(vString),blocked_status:vOptional(vString),close_status:vOptional(vString),canceled_status:vOptional(vString)})),type_workflows:vOptional(vArray(typeWorkflowDefinition)),unknown_field_policy:vOptional(vLiteral(...RUNTIME_UNKNOWN_FIELD_POLICY_VALUES))})),governanceSettings=vOptional(vObject({preset:vOptional(vLiteral(...GOVERNANCE_PRESET_VALUES)),ownership_enforcement:vOptional(vLiteral("none","warn","strict")),create_mode_default:vOptional(vLiteral("progressive","strict")),close_validation_default:vOptional(vLiteral("off","warn","strict")),require_close_reason:vOptional(vBoolean),parent_reference:vOptional(vLiteral("warn","strict_error")),metadata_profile:vOptional(vLiteral("core","strict","custom")),force_required_for_stale_lock:vOptional(vBoolean),create_default_type:vOptional(vString),workflow_enforcement:vOptional(vLiteral("off","warn","strict")),start_blocker_enforcement:vOptional(vLiteral("off","warn","strict")),duplicate_detection_mode:vOptional(vLiteral("off","advisory","strict")),duplicate_detection_threshold:vOptional(vNumber({min:0,max:1})),duplicate_detection_limit:vOptional(vNumber({int:!0,min:0,max:20}))})),extensionPolicyOverride=vObject({name:vString,disabled:vOptional(vBoolean),require_trusted:vOptional(vBoolean),require_provenance:vOptional(vBoolean),sandbox_profile:vOptional(vLiteral("none","restricted","strict")),allowed_capabilities:vOptional(vArray(vString)),blocked_capabilities:vOptional(vArray(vString)),allowed_surfaces:vOptional(vArray(vString)),blocked_surfaces:vOptional(vArray(vString)),allowed_commands:vOptional(vArray(vString)),blocked_commands:vOptional(vArray(vString)),allowed_actions:vOptional(vArray(vString)),blocked_actions:vOptional(vArray(vString)),allowed_services:vOptional(vArray(vString)),blocked_services:vOptional(vArray(vString))}),pmMaxVersionExceededModeLiteral=vLiteral("block","warn"),pmMaxVersionExceededMode=input=>typeof input=="string"?pmMaxVersionExceededModeLiteral(input):vObject({global:vOptional(pmMaxVersionExceededModeLiteral),project:vOptional(pmMaxVersionExceededModeLiteral)})(input),extensionPolicy=vOptional(vObject({mode:vOptional(vLiteral("off","warn","enforce")),trust_mode:vOptional(vLiteral("off","warn","enforce")),pm_max_version_exceeded_mode:vOptional(pmMaxVersionExceededMode),require_provenance:vOptional(vBoolean),trusted_extensions:vOptional(vArray(vString)),default_sandbox_profile:vOptional(vLiteral("none","restricted","strict")),allowed_extensions:vOptional(vArray(vString)),blocked_extensions:vOptional(vArray(vString)),allowed_capabilities:vOptional(vArray(vString)),blocked_capabilities:vOptional(vArray(vString)),allowed_surfaces:vOptional(vArray(vString)),blocked_surfaces:vOptional(vArray(vString)),allowed_commands:vOptional(vArray(vString)),blocked_commands:vOptional(vArray(vString)),allowed_actions:vOptional(vArray(vString)),blocked_actions:vOptional(vArray(vString)),allowed_services:vOptional(vArray(vString)),blocked_services:vOptional(vArray(vString)),extension_overrides:vOptional(vArray(extensionPolicyOverride))})),harnessSignalLiteral=vBoundedNormalizedString(128),harnessSignalDescriptor=vObject({harness:vBoundedNormalizedString(128,/^[a-z0-9]+(?:-[a-z0-9]+)*$/u),environment_keys:vOptional(vArray(harnessSignalLiteral,64)),model_environment_keys:vOptional(vArray(harnessSignalLiteral,64)),session_environment_keys:vOptional(vArray(harnessSignalLiteral,64)),provenance_environment_keys:vOptional(vRecordOf(vArray(harnessSignalLiteral,64))),provenance_resolvers:vOptional(vRecordOf(vLiteral("ai_agent_version","claude_session_file"))),provenance_unavailable_dimensions:vOptional(vArray(harnessSignalLiteral,64)),argv_markers:vOptional(vArray(harnessSignalLiteral,64)),client_names:vOptional(vArray(harnessSignalLiteral,64))}),SETTINGS_SHAPE={version:vNumber({int:!0}),id_prefix:vString,ids:vOptional(vObject({token_length:vOptional(vNumber({int:!0,min:4,max:12}))})),author_default:vString,agent_identity:vOptional(vObject({probes_enabled:vOptional(vBoolean),identity_vocabulary:vOptional(vObject({version:vNumber({int:!0,positive:!0}),aliases:vRecordOf(vBoundedNormalizedString(128,/^[a-z0-9]+(?:-[a-z0-9]+)*$/u))})),harness_signals:vArray(harnessSignalDescriptor)})),mutation_guard:vOptional(vObject({require_attributed_author:vOptional(vBoolean),secret_guard:vOptional(vLiteral("off","advise","block")),stale_in_progress_hours:vOptional(vNumber({int:!0,positive:!0}))})),item_format:vOptional(vLiteral("toon","json_markdown")),locks:vObject({ttl_seconds:vNumber({int:!0}),wait_ms:vOptional(vNumber({int:!0,min:0}))}),checkpoints:vOptional(vObject({retention_days:vOptional(vNumber({int:!0,positive:!0}))})),output:vObject({default_format:vLiteral("toon","json")}),ux:vOptional(vObject({deprecation_hints:vOptional(vBoolean)})),history:vOptional(vObject({missing_stream:vLiteral("auto_create","strict_error"),compact_policy:vOptional(vObject({enabled:vOptional(vBoolean),max_entries:vOptional(vNumber({int:!0,positive:!0})),trigger:vOptional(vLiteral("health_warn","auto"))}))})),validation:vOptional(vObject({sprint_release_format:vLiteral("warn","strict_error"),parent_reference:vOptional(vLiteral("warn","strict_error")),metadata_profile:vOptional(vLiteral("core","strict","custom")),metadata_required_fields:vOptional(vArray(vString)),lifecycle_stale_blocker_reason_patterns:vOptional(vArray(vString)),lifecycle_closure_like_blocked_reason_patterns:vOptional(vArray(vString)),lifecycle_closure_like_resolution_patterns:vOptional(vArray(vString)),lifecycle_closure_like_actual_result_patterns:vOptional(vArray(vString)),estimate_defaults_by_type:vOptional(vRecordOf(vNumber({int:!0,positive:!0})))})),governance:governanceSettings,workflow:vOptional(vObject({definition_of_done:vArray(vString)})),testing:vOptional(vObject({record_results_to_items:vBoolean,allow_untrusted_linked_tests:vOptional(vBoolean)})),telemetry:vOptional(vObject({enabled:vBoolean,first_run_prompt_completed:vOptional(vBoolean),capture_level:vOptional(vLiteral("minimal","redacted","max")),endpoint:vOptional(vString),installation_id:vOptional(vString),retention_days:vOptional(vNumber({int:!0,positive:!0}))})),agent_guidance:vOptional(vObject({prompt_completed:vOptional(vBoolean),declined:vOptional(vBoolean),declined_at:vOptional(vString),template_version:vOptional(vNumber({int:!0,positive:!0})),last_checked_files:vOptional(vArray(vString))})),item_types:vOptional(vObject({definitions:vArray(itemTypeDefinition)})),schema:runtimeSchemaSettings,context:vOptional(vObject({default_depth:vOptional(vLiteral("brief","standard","deep")),activity_limit:vOptional(vNumber({int:!0,positive:!0})),stale_threshold_days:vOptional(vNumber({int:!0,positive:!0})),next_ranking_policy:vOptional(vLiteral("priority_floor","weighted")),sections:vOptional(vObject({hierarchy:vOptional(vBoolean),activity:vOptional(vBoolean),progress:vOptional(vBoolean),recently_created:vOptional(vBoolean),unparented:vOptional(vBoolean),blockers:vOptional(vBoolean),files:vOptional(vBoolean),workload:vOptional(vBoolean),staleness:vOptional(vBoolean),tests:vOptional(vBoolean)}))})),extensions:vObject({enabled:vArray(vString),disabled:vArray(vString),policy:extensionPolicy}),search:vObject({score_threshold:vNumber(),hybrid_semantic_weight:vOptional(vNumber()),max_results:vNumber({int:!0}),embedding_model:vString,embedding_corpus_max_characters:vOptional(vNumber()),embedding_batch_size:vNumber({int:!0}),embedding_timeout_ms:vOptional(vNumber({int:!0})),scanner_max_batch_retries:vNumber({int:!0}),provider:vOptional(vString),default_mode:vOptional(vLiteral("auto","keyword","semantic","hybrid")),corpus_fields:vOptional(vArray(vString)),mutation_refresh_policy:vOptional(vLiteral("cache_only","semantic_configured","semantic_auto")),query_expansion:vOptional(vObject({enabled:vOptional(vBoolean),provider:vOptional(vString)})),rerank:vOptional(vObject({enabled:vOptional(vBoolean),model:vOptional(vString),top_k:vOptional(vNumber({int:!0,positive:!0}))})),bm25:vOptional(vObject({k1:vOptional(vNumber()),b:vOptional(vNumber())}))}),providers:vObject({openai:vObject({base_url:vString,api_key:vString,model:vString}),ollama:vObject({base_url:vString,model:vString})}),vector_store:vObject({adapter:vOptional(vString),collection_name:vOptional(vString),qdrant:vObject({url:vString,api_key:vString}),lancedb:vObject({path:vString})})},settingsCheck=vObject(SETTINGS_SHAPE),CORE_SETTINGS_SECTION_KEYS=Object.freeze(Object.keys(SETTINGS_SHAPE));function validateSettings(raw){const result=settingsCheck(raw);return result.ok?{success:!0,data:result.value}:{success:!1,path:result.path.join(".")}}export{CORE_SETTINGS_SECTION_KEYS,validateSettings};
2
2
  //# sourceMappingURL=settings-validator.js.map
@@ -1,4 +1,4 @@
1
- (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f9ff37ec-3a6f-5496-b59d-cdf2cce3a63a")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{lstat,realpath}from"node:fs/promises";import path from"node:path";import{CORE_SETTINGS_SECTION_KEYS,validateSettings}from"./settings-validator.js";import{runActiveOnReadHooks,runActiveOnWriteHooks}from"../extensions/index.js";import{EXIT_CODE,GOVERNANCE_PRESET_DEFAULTS,SETTINGS_DEFAULTS}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{resolveAuthor}from"../shared/author.js";import{isFileAbsentError,readFileIfExists,readRegularFile,transactionPreviewNonRegularFileError}from"../fs/fs-utils.js";import{mutateWorkspaceJsonWithHistory}from"../history/workspace-history.js";import{reconcileSettingsSnapshot}from"./settings-concurrency.js";import{DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,filePathForSchemaSection,loadRuntimeSchemaFromOptionalFiles,normalizeRuntimeSchemaSettings}from"../schema/runtime-schema.js";import{getSettingsPath}from"./paths.js";import{orderObject,stableValueEquals}from"../shared/serialization.js";import{normalizeItemTypeDefinition}from"../item/item-type-definition.js";import{normalizeEstimateDefaultOverrides}from"../validate/estimate-defaults.js";import{clearSettingsReadCache,collectSettingsReadCacheSignatures,getSettingsReadCacheEntry,setSettingsReadCacheEntry,settingsReadCacheSignaturesEqual}from"./settings-read-cache.js";const configurationOnlySettingsRoots=new AsyncLocalStorage;async function runWithConfigurationOnlySettings(pmRoot,run,isEnabled=()=>!0){const roots=new Set([path.resolve(pmRoot)]);try{roots.add(await realpath(pmRoot))}catch{}return configurationOnlySettingsRoots.run([...configurationOnlySettingsRoots.getStore()??[],[roots,isEnabled]],run)}function isConfigurationOnlySettingsRead(pmRoot){const root=path.resolve(pmRoot);return configurationOnlySettingsRoots.getStore()?.some(([roots,isEnabled])=>roots.has(root)&&isEnabled())??!1}const SETTINGS_WRITE_OP="settings:write",SETTINGS_PERSIST_SOURCE_SYMBOL=Symbol("pm.settings.persist_source"),SETTINGS_FALLBACK_ORIGIN_SYMBOL=Symbol("pm.settings.fallback_origin"),SETTINGS_FALLBACK_BASELINE_SYMBOL=Symbol("pm.settings.fallback_baseline"),MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH=128,DUPLICATE_DETECTION_MODES=new Set(["off","advisory","strict"]);function resolveGovernanceKnobsFromPreset(preset){return structuredClone(GOVERNANCE_PRESET_DEFAULTS[preset])}function normalizeGovernancePreset(value){return value==="minimal"||value==="default"||value==="strict"||value==="custom"?value:SETTINGS_DEFAULTS.governance.preset}function withGovernanceExtras(base,governance){const createDefaultType=typeof governance.create_default_type=="string"?governance.create_default_type.trim():void 0;return createDefaultType&&createDefaultType.length>0&&(base.create_default_type=createDefaultType),(governance.workflow_enforcement==="off"||governance.workflow_enforcement==="warn"||governance.workflow_enforcement==="strict")&&(base.workflow_enforcement=governance.workflow_enforcement),governance.require_close_reason===!1&&(base.require_close_reason=!1),base.duplicate_detection_mode=governance.duplicate_detection_mode,base.duplicate_detection_threshold=governance.duplicate_detection_threshold,base.duplicate_detection_limit=governance.duplicate_detection_limit,base}function normalizeGovernanceForPersist(governance){return governance.preset==="custom"?withGovernanceExtras({preset:"custom",ownership_enforcement:governance.ownership_enforcement,create_mode_default:governance.create_mode_default,close_validation_default:governance.close_validation_default,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,force_required_for_stale_lock:governance.force_required_for_stale_lock},governance):withGovernanceExtras({preset:governance.preset},governance)}function resolveGovernanceExtras(rawGovernance){const createDefaultType=typeof rawGovernance.create_default_type=="string"?rawGovernance.create_default_type.trim():void 0,extras={};createDefaultType&&createDefaultType.length>0&&(extras.create_default_type=createDefaultType),(rawGovernance.workflow_enforcement==="off"||rawGovernance.workflow_enforcement==="warn"||rawGovernance.workflow_enforcement==="strict")&&(extras.workflow_enforcement=rawGovernance.workflow_enforcement),typeof rawGovernance.require_close_reason=="boolean"&&(extras.require_close_reason=rawGovernance.require_close_reason),DUPLICATE_DETECTION_MODES.has(String(rawGovernance.duplicate_detection_mode))&&(extras.duplicate_detection_mode=rawGovernance.duplicate_detection_mode);const threshold=rawGovernance.duplicate_detection_threshold;[typeof threshold=="number",Number.isFinite(threshold),Number(threshold)>=0,Number(threshold)<=1].every(Boolean)&&(extras.duplicate_detection_threshold=threshold);const limit=rawGovernance.duplicate_detection_limit;return[typeof limit=="number",Number.isSafeInteger(limit),Number(limit)>=0,Number(limit)<=20].every(Boolean)&&(extras.duplicate_detection_limit=limit),extras}function resolveGovernanceKnobs(settings){const rawGovernance=settings.governance??{},preset=normalizeGovernancePreset(rawGovernance.preset),extras=resolveGovernanceExtras(rawGovernance);if(preset==="custom"){const baseline2=resolveGovernanceKnobsFromPreset("default"),requireCloseReason2=extras.require_close_reason??baseline2.require_close_reason;return{preset,ownership_enforcement:rawGovernance.ownership_enforcement??baseline2.ownership_enforcement,create_mode_default:rawGovernance.create_mode_default??baseline2.create_mode_default,close_validation_default:rawGovernance.close_validation_default??baseline2.close_validation_default,parent_reference:rawGovernance.parent_reference??baseline2.parent_reference,metadata_profile:rawGovernance.metadata_profile??baseline2.metadata_profile,force_required_for_stale_lock:rawGovernance.force_required_for_stale_lock??baseline2.force_required_for_stale_lock,...extras,require_close_reason:requireCloseReason2,duplicate_detection_mode:extras.duplicate_detection_mode??baseline2.duplicate_detection_mode,duplicate_detection_threshold:extras.duplicate_detection_threshold??baseline2.duplicate_detection_threshold,duplicate_detection_limit:extras.duplicate_detection_limit??baseline2.duplicate_detection_limit}}const baseline=resolveGovernanceKnobsFromPreset(preset),requireCloseReason=extras.require_close_reason??baseline.require_close_reason;return{preset,...baseline,...extras,require_close_reason:requireCloseReason}}function cloneDefaults(){return structuredClone(SETTINGS_DEFAULTS)}function normalizeSearchMutationRefreshPolicy(value){return value==="cache_only"||value==="semantic_configured"||value==="semantic_auto"?value:SETTINGS_DEFAULTS.search.mutation_refresh_policy}function normalizeSearchDefaultMode(value){return value==="auto"||value==="keyword"||value==="semantic"||value==="hybrid"?value:"auto"}function normalizeSearchQueryExpansionEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.query_expansion.enabled}function normalizeSearchQueryExpansionProvider(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.query_expansion.provider:value.trim()}function normalizeSearchRerankEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.rerank.enabled}function normalizeSearchRerankModel(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.rerank.model:value.trim()}function normalizeSearchRerankTopK(value){return typeof value=="number"&&Number.isFinite(value)&&Number.isInteger(value)&&value>0?value:SETTINGS_DEFAULTS.search.rerank.top_k}function normalizeVectorStoreCollectionName(value){if(typeof value!="string")return SETTINGS_DEFAULTS.vector_store.collection_name;const truncated=value.trim().replaceAll(/[^a-zA-Z0-9_-]/g,"_").slice(0,MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH);return truncated.length>0?truncated:SETTINGS_DEFAULTS.vector_store.collection_name}function cloneOptionalArray(value){return{present:Array.isArray(value),values:Array.isArray(value)?structuredClone(value):[]}}function buildSettingsPersistSourceSnapshot(parsedSettings,runtimeSettings){const sourceSchema=parsedSettings.schema,sourceStatuses=cloneOptionalArray(sourceSchema?.statuses),sourceFields=cloneOptionalArray(sourceSchema?.fields),sourceTypeWorkflows=cloneOptionalArray(sourceSchema?.type_workflows);return{persisted_settings:structuredClone(parsedSettings),source_settings:structuredClone(parsedSettings),has_source_item_type_definitions:Array.isArray(parsedSettings.item_types?.definitions),source_item_type_definitions:normalizeItemTypeDefinitions(parsedSettings.item_types?.definitions),has_source_schema_statuses:sourceStatuses.present,source_schema_statuses:sourceStatuses.values,has_source_schema_fields:sourceFields.present,source_schema_fields:sourceFields.values,has_source_schema_type_workflows:sourceTypeWorkflows.present,source_schema_type_workflows:sourceTypeWorkflows.values,runtime_item_type_definitions:normalizeItemTypeDefinitions(runtimeSettings.item_types?.definitions),runtime_schema_statuses:structuredClone(runtimeSettings.schema.statuses),runtime_schema_fields:structuredClone(runtimeSettings.schema.fields),runtime_schema_type_workflows:structuredClone(runtimeSettings.schema.type_workflows??[])}}function attachSettingsPersistSourceSnapshot(settings,source){Object.defineProperty(settings,SETTINGS_PERSIST_SOURCE_SYMBOL,{value:source,writable:!0,configurable:!0,enumerable:!1})}function getSettingsPersistSourceSnapshot(settings){const candidate=settings[SETTINGS_PERSIST_SOURCE_SYMBOL];if(!(!candidate||typeof candidate!="object"))return candidate}function persistSelectedItemFormat(settings){const source=getSettingsPersistSourceSnapshot(settings);if(source){const detachedSource=structuredClone(source);detachedSource.source_settings.item_format=settings.item_format,attachSettingsPersistSourceSnapshot(settings,detachedSource)}}function cloneSettingsReadResult(result){const clonedSettings=structuredClone(result.settings),persistSource=getSettingsPersistSourceSnapshot(result.settings);persistSource&&attachSettingsPersistSourceSnapshot(clonedSettings,persistSource);const fallbackOrigin=getSettingsFallbackOrigin(result.settings);return fallbackOrigin!==void 0&&markSettingsFallbackOrigin(clonedSettings,fallbackOrigin),{settings:clonedSettings,metadata:{has_explicit_item_format:result.metadata.has_explicit_item_format},warnings:[...result.warnings]}}function resolveSettingsReadTrackedPaths(pmRoot,schema,settingsPath){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);return[settingsPath,filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types),filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses),filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields),filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows)]}async function cacheSettingsReadResult(pmRoot,trackedPaths,result){const signatures=await collectSettingsReadCacheSignatures(trackedPaths);setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures,value:cloneSettingsReadResult(result)})}async function cacheSettingsReadResultSafe(pmRoot,trackedPaths,result){try{await cacheSettingsReadResult(pmRoot,trackedPaths,result)}catch{clearSettingsReadCache(pmRoot)}}function findSettingsReadCacheSignature(signatures,targetPath){return signatures.find(signature=>signature.path===targetPath)}function selectedSettingsReadCacheSignaturesEqual(before,after,targetPaths){for(const targetPath of targetPaths){const beforeSignature=findSettingsReadCacheSignature(before,targetPath),afterSignature=findSettingsReadCacheSignature(after,targetPath);if(!beforeSignature||!afterSignature||!settingsReadCacheSignaturesEqual([beforeSignature],[afterSignature]))return!1}return!0}async function cacheSettingsReadResultIfStable(pmRoot,trackedPaths,result,stableSignatures,stablePaths){try{const currentSignatures=await collectSettingsReadCacheSignatures(trackedPaths);if(!selectedSettingsReadCacheSignaturesEqual(stableSignatures,currentSignatures,stablePaths)){clearSettingsReadCache(pmRoot);return}setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:currentSignatures,value:cloneSettingsReadResult(result)})}catch{clearSettingsReadCache(pmRoot)}}function resolvePersistedFileBackedSchemaSections(settings,source){const normalizedSchema=normalizeRuntimeSchemaSettings(settings.schema),currentItemTypeDefinitions=normalizeItemTypeDefinitions(settings.item_types?.definitions);if(!source)return{item_type_definitions:currentItemTypeDefinitions,schema_statuses:normalizedSchema.statuses,schema_fields:normalizedSchema.fields,schema_type_workflows:normalizedSchema.type_workflows};const currentTypeWorkflows=normalizedSchema.type_workflows??[],itemTypeDefinitionsUnchanged=stableValueEquals(currentItemTypeDefinitions,source.runtime_item_type_definitions),schemaStatusesUnchanged=stableValueEquals(normalizedSchema.statuses,source.runtime_schema_statuses),schemaFieldsUnchanged=stableValueEquals(normalizedSchema.fields,source.runtime_schema_fields),schemaTypeWorkflowsUnchanged=stableValueEquals(currentTypeWorkflows,source.runtime_schema_type_workflows);return{item_type_definitions:itemTypeDefinitionsUnchanged?source.has_source_item_type_definitions?normalizeItemTypeDefinitions(source.source_item_type_definitions):[]:currentItemTypeDefinitions,schema_statuses:schemaStatusesUnchanged?source.has_source_schema_statuses?structuredClone(source.source_schema_statuses):[]:normalizedSchema.statuses,schema_fields:schemaFieldsUnchanged?source.has_source_schema_fields?structuredClone(source.source_schema_fields):[]:normalizedSchema.fields,schema_type_workflows:schemaTypeWorkflowsUnchanged?source.has_source_schema_type_workflows?structuredClone(source.source_schema_type_workflows):void 0:normalizedSchema.type_workflows}}function markSettingsFallbackOrigin(settings,warning){Object.defineProperty(settings,SETTINGS_FALLBACK_ORIGIN_SYMBOL,{value:warning,writable:!0,configurable:!0,enumerable:!1})}function isSettingsReadFallback(settings){return getSettingsFallbackOrigin(settings)!==void 0}function getSettingsFallbackOrigin(settings){const candidate=settings[SETTINGS_FALLBACK_ORIGIN_SYMBOL];return typeof candidate=="string"?candidate:void 0}function getSettingsFallbackBaseline(settings){return settings[SETTINGS_FALLBACK_BASELINE_SYMBOL]}function setSettingsFallbackBaseline(settings,baseline){Object.defineProperty(settings,SETTINGS_FALLBACK_BASELINE_SYMBOL,{value:baseline,writable:!0,configurable:!0,enumerable:!1})}function buildFallbackSettingsReadResult(warning){const settings=cloneDefaults();return warning!==void 0&&markSettingsFallbackOrigin(settings,warning),{settings,metadata:{has_explicit_item_format:!1},warnings:warning?[warning]:[]}}function hasExplicitItemFormat(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return!1;const itemFormat=raw.item_format;return itemFormat==="toon"||itemFormat==="json_markdown"}function normalizeStringList(values){return[...new Set((values??[]).map(value=>value.trim()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeAgentGuidanceSettings(value){const defaults=SETTINGS_DEFAULTS.agent_guidance,templateVersion=value?.template_version;return{prompt_completed:value?.prompt_completed===!0,declined:value?.declined===!0,declined_at:typeof value?.declined_at=="string"?value.declined_at:defaults.declined_at,template_version:typeof templateVersion=="number"&&Number.isInteger(templateVersion)&&templateVersion>0?templateVersion:defaults.template_version,last_checked_files:normalizeStringList(value?.last_checked_files??defaults.last_checked_files)}}function normalizeLowerStringList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeExtensionPolicyMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.mode}function normalizeExtensionTrustMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.trust_mode}function normalizeExtensionSandboxProfile(value){return value==="none"||value==="restricted"||value==="strict"?value:SETTINGS_DEFAULTS.extensions.policy.default_sandbox_profile}function normalizeExtensionPolicyOverride(override){const name=override.name.trim().toLowerCase();if(name.length===0)return null;const normalized={name};override.disabled===!0&&(normalized.disabled=!0),override.require_trusted===!0&&(normalized.require_trusted=!0),override.require_provenance===!0&&(normalized.require_provenance=!0),override.sandbox_profile!==void 0&&(normalized.sandbox_profile=normalizeExtensionSandboxProfile(override.sandbox_profile));const allowedCapabilities=normalizeLowerStringList(override.allowed_capabilities),blockedCapabilities=normalizeLowerStringList(override.blocked_capabilities),allowedSurfaces=normalizeLowerStringList(override.allowed_surfaces),blockedSurfaces=normalizeLowerStringList(override.blocked_surfaces),allowedCommands=normalizeLowerStringList(override.allowed_commands),blockedCommands=normalizeLowerStringList(override.blocked_commands),allowedActions=normalizeLowerStringList(override.allowed_actions),blockedActions=normalizeLowerStringList(override.blocked_actions),allowedServices=normalizeLowerStringList(override.allowed_services),blockedServices=normalizeLowerStringList(override.blocked_services);return allowedCapabilities.length>0&&(normalized.allowed_capabilities=allowedCapabilities),blockedCapabilities.length>0&&(normalized.blocked_capabilities=blockedCapabilities),allowedSurfaces.length>0&&(normalized.allowed_surfaces=allowedSurfaces),blockedSurfaces.length>0&&(normalized.blocked_surfaces=blockedSurfaces),allowedCommands.length>0&&(normalized.allowed_commands=allowedCommands),blockedCommands.length>0&&(normalized.blocked_commands=blockedCommands),allowedActions.length>0&&(normalized.allowed_actions=allowedActions),blockedActions.length>0&&(normalized.blocked_actions=blockedActions),allowedServices.length>0&&(normalized.allowed_services=allowedServices),blockedServices.length>0&&(normalized.blocked_services=blockedServices),normalized}function normalizeExtensionPolicyOverrides(overrides){const dedupedByName=new Map;for(const override of overrides??[]){const normalized=normalizeExtensionPolicyOverride(override);normalized&&dedupedByName.set(normalized.name,normalized)}return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function normalizePmMaxVersionExceededModeValue(value){return value==="block"||value==="warn"?value:void 0}function normalizePmMaxVersionExceededModeSetting(value){if(typeof value=="string")return normalizePmMaxVersionExceededModeValue(value);if(typeof value=="object"&&value!==null&&!Array.isArray(value)){const global2=normalizePmMaxVersionExceededModeValue(value.global),project=normalizePmMaxVersionExceededModeValue(value.project);return global2===void 0&&project===void 0?void 0:{...global2!==void 0?{global:global2}:{},...project!==void 0?{project}:{}}}}function normalizeExtensionPolicyList(policy,key){return normalizeLowerStringList(policy?.[key]??SETTINGS_DEFAULTS.extensions.policy[key])}function normalizeExtensionPolicySettings(policy){const pmMaxVersionExceededMode=normalizePmMaxVersionExceededModeSetting(policy?.pm_max_version_exceeded_mode);return{mode:normalizeExtensionPolicyMode(policy?.mode),trust_mode:normalizeExtensionTrustMode(policy?.trust_mode),...pmMaxVersionExceededMode!==void 0?{pm_max_version_exceeded_mode:pmMaxVersionExceededMode}:{},require_provenance:policy?.require_provenance===!0,trusted_extensions:normalizeExtensionPolicyList(policy,"trusted_extensions"),default_sandbox_profile:normalizeExtensionSandboxProfile(policy?.default_sandbox_profile),allowed_extensions:normalizeExtensionPolicyList(policy,"allowed_extensions"),blocked_extensions:normalizeExtensionPolicyList(policy,"blocked_extensions"),allowed_capabilities:normalizeExtensionPolicyList(policy,"allowed_capabilities"),blocked_capabilities:normalizeExtensionPolicyList(policy,"blocked_capabilities"),allowed_surfaces:normalizeExtensionPolicyList(policy,"allowed_surfaces"),blocked_surfaces:normalizeExtensionPolicyList(policy,"blocked_surfaces"),allowed_commands:normalizeExtensionPolicyList(policy,"allowed_commands"),blocked_commands:normalizeExtensionPolicyList(policy,"blocked_commands"),allowed_actions:normalizeExtensionPolicyList(policy,"allowed_actions"),blocked_actions:normalizeExtensionPolicyList(policy,"blocked_actions"),allowed_services:normalizeExtensionPolicyList(policy,"allowed_services"),blocked_services:normalizeExtensionPolicyList(policy,"blocked_services"),extension_overrides:normalizeExtensionPolicyOverrides(policy?.extension_overrides??SETTINGS_DEFAULTS.extensions.policy.extension_overrides)}}function normalizeValidationMetadataRequiredFields(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase().replaceAll("-","_")))].filter(value=>value.length>0).sort((left,right)=>left.localeCompare(right)).filter(value=>["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"].includes(value))}function normalizeValidationPatternList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function valueOrDefault(value,fallback){return value===void 0?fallback:value}function recordOrEmpty(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:{}}function arrayOrEmpty(value){return Array.isArray(value)?value:[]}function buildValidationSettings(settings,defaults,governance){return{...defaults.validation,...settings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(settings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_stale_blocker_reason_patterns??defaults.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_blocked_reason_patterns??defaults.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_resolution_patterns??defaults.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_actual_result_patterns??defaults.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(settings.validation?.estimate_defaults_by_type)}}function buildTelemetrySettings(settings,defaults){return{enabled:settings.telemetry?.enabled??defaults.telemetry.enabled,first_run_prompt_completed:settings.telemetry?.first_run_prompt_completed??defaults.telemetry.first_run_prompt_completed,capture_level:settings.telemetry?.capture_level??defaults.telemetry.capture_level,endpoint:settings.telemetry?.endpoint??defaults.telemetry.endpoint,installation_id:settings.telemetry?.installation_id??defaults.telemetry.installation_id,retention_days:settings.telemetry?.retention_days??defaults.telemetry.retention_days}}function buildSearchSettings(settings,defaults){return{...defaults.search,...settings.search,default_mode:normalizeSearchDefaultMode(settings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(settings.search?.mutation_refresh_policy),query_expansion:{...defaults.search.query_expansion,...settings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(settings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(settings.search?.query_expansion?.provider)},rerank:{...defaults.search.rerank,...settings.search?.rerank,enabled:normalizeSearchRerankEnabled(settings.search?.rerank?.enabled),model:normalizeSearchRerankModel(settings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(settings.search?.rerank?.top_k)}}}function buildVectorStoreSettings(settings,defaults){return{adapter:settings.vector_store.adapter??defaults.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(settings.vector_store.collection_name),qdrant:{...defaults.vector_store.qdrant,...settings.vector_store.qdrant},lancedb:{...defaults.vector_store.lancedb,...settings.vector_store.lancedb}}}function normalizeSettingsItemFormat(settings,defaults){return settings.item_format==="json_markdown"?"toon":settings.item_format??defaults.item_format}function buildContextSettings(settings,defaults){return{default_depth:settings.context?.default_depth??defaults.context.default_depth,activity_limit:settings.context?.activity_limit??defaults.context.activity_limit,stale_threshold_days:settings.context?.stale_threshold_days??defaults.context.stale_threshold_days,next_ranking_policy:settings.context?.next_ranking_policy??defaults.context.next_ranking_policy,sections:{...defaults.context.sections,...settings.context?.sections}}}function buildProviderSettings(settings,defaults){return{openai:{...defaults.providers.openai,...settings.providers.openai},ollama:{...defaults.providers.ollama,...settings.providers.ollama}}}function normalizeItemTypeDefinitions(definitions){const normalized=(definitions??[]).map(definition=>normalizeItemTypeDefinition(definition)).filter(definition=>definition!==null),dedupedByName=new Map;for(const definition of normalized)dedupedByName.set(definition.name.toLowerCase(),definition);return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function mergeSettings(settings){const defaults=cloneDefaults(),governance=resolveGovernanceKnobs({governance:settings.governance??{preset:"default"}});return{...defaults,...settings,item_format:normalizeSettingsItemFormat(settings,defaults),locks:{...defaults.locks,...settings.locks},ids:{...defaults.ids,...settings.ids},agent_identity:structuredClone(settings.agent_identity??defaults.agent_identity),mutation_guard:{...defaults.mutation_guard,...settings.mutation_guard},checkpoints:{...defaults.checkpoints,...settings.checkpoints},output:{...defaults.output,...settings.output},ux:{...defaults.ux,...settings.ux},history:{...defaults.history,...settings.history,compact_policy:{...defaults.history.compact_policy,...settings.history?.compact_policy}},validation:buildValidationSettings(settings,defaults,governance),governance,workflow:{definition_of_done:[...settings.workflow?.definition_of_done??defaults.workflow.definition_of_done]},testing:{record_results_to_items:settings.testing?.record_results_to_items??defaults.testing.record_results_to_items,allow_untrusted_linked_tests:settings.testing?.allow_untrusted_linked_tests??defaults.testing.allow_untrusted_linked_tests},telemetry:buildTelemetrySettings(settings,defaults),agent_guidance:normalizeAgentGuidanceSettings(settings.agent_guidance??defaults.agent_guidance),item_types:{definitions:normalizeItemTypeDefinitions(settings.item_types?.definitions)},schema:normalizeRuntimeSchemaSettings(settings.schema??defaults.schema),context:buildContextSettings(settings,defaults),extensions:{enabled:[...settings.extensions.enabled],disabled:[...settings.extensions.disabled],policy:normalizeExtensionPolicySettings(settings.extensions.policy??defaults.extensions.policy)},search:buildSearchSettings(settings,defaults),providers:buildProviderSettings(settings,defaults),vector_store:buildVectorStoreSettings(settings,defaults)}}function orderSerializedSettingsSections(ordered){ordered.agent_identity=orderObject(ordered.agent_identity,["probes_enabled","identity_vocabulary","harness_signals"]);const orderedAgentIdentity=ordered.agent_identity;Object.hasOwn(orderedAgentIdentity,"identity_vocabulary")&&(orderedAgentIdentity.identity_vocabulary=orderObject(recordOrEmpty(orderedAgentIdentity.identity_vocabulary),["version","aliases"])),ordered.agent_identity.harness_signals=arrayOrEmpty(ordered.agent_identity.harness_signals).map(entry=>orderObject(recordOrEmpty(entry),["harness","environment_keys","model_environment_keys","session_environment_keys","provenance_environment_keys","provenance_resolvers","provenance_unavailable_dimensions","argv_markers","client_names"])),ordered.locks=orderObject(ordered.locks,["ttl_seconds","wait_ms"]),ordered.ids=orderObject(ordered.ids,["token_length"]),ordered.mutation_guard=orderObject(ordered.mutation_guard,["require_attributed_author","secret_guard","stale_in_progress_hours"]),ordered.checkpoints=orderObject(ordered.checkpoints,["retention_days"]),ordered.output=orderObject(ordered.output,["default_format"]),ordered.ux=orderObject(ordered.ux,["deprecation_hints"]),ordered.history=orderObject(ordered.history,["missing_stream","compact_policy"]),ordered.validation=orderObject(ordered.validation,["sprint_release_format","parent_reference","metadata_profile","metadata_required_fields","lifecycle_stale_blocker_reason_patterns","lifecycle_closure_like_blocked_reason_patterns","lifecycle_closure_like_resolution_patterns","lifecycle_closure_like_actual_result_patterns","estimate_defaults_by_type"]),ordered.governance=orderObject(ordered.governance,["preset","ownership_enforcement","create_mode_default","close_validation_default","require_close_reason","parent_reference","metadata_profile","force_required_for_stale_lock","create_default_type","workflow_enforcement","duplicate_detection_mode","duplicate_detection_threshold","duplicate_detection_limit"]),ordered.workflow=orderObject(ordered.workflow,["definition_of_done"]),ordered.testing=orderObject(ordered.testing,["record_results_to_items","allow_untrusted_linked_tests"]),ordered.telemetry=orderObject(ordered.telemetry,["enabled","first_run_prompt_completed","capture_level","endpoint","installation_id","retention_days"]),ordered.agent_guidance=orderObject(ordered.agent_guidance,["prompt_completed","declined","declined_at","template_version","last_checked_files"]),ordered.item_types=orderObject(ordered.item_types,["definitions"]),ordered.schema=orderObject(ordered.schema,["version","files","statuses","fields","workflow","type_workflows","unknown_field_policy"]),ordered.schema.files=orderObject(recordOrEmpty(ordered.schema.files),["types","statuses","fields","workflows"]),ordered.schema.workflow=orderObject(recordOrEmpty(ordered.schema.workflow),["draft_status","open_status","in_progress_status","blocked_status","close_status","canceled_status"]),ordered.context=orderObject(ordered.context,["default_depth","activity_limit","stale_threshold_days","next_ranking_policy","sections"]),ordered.context.sections=orderObject(recordOrEmpty(ordered.context.sections),["hierarchy","activity","progress","blockers","files","workload","staleness","tests"]),ordered.extensions=orderObject(ordered.extensions,["enabled","disabled","policy"]),ordered.extensions.policy=orderObject(recordOrEmpty(ordered.extensions.policy),["mode","trust_mode","pm_max_version_exceeded_mode","require_provenance","trusted_extensions","default_sandbox_profile","allowed_extensions","blocked_extensions","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services","extension_overrides"]),ordered.extensions.policy.extension_overrides=arrayOrEmpty(ordered.extensions.policy.extension_overrides).map(entry=>orderObject(recordOrEmpty(entry),["name","disabled","require_trusted","require_provenance","sandbox_profile","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"])),ordered.search=orderObject(ordered.search,["score_threshold","hybrid_semantic_weight","max_results","embedding_model","embedding_corpus_max_characters","embedding_batch_size","embedding_timeout_ms","scanner_max_batch_retries","provider","default_mode","mutation_refresh_policy","query_expansion","rerank"]),ordered.search.query_expansion=orderObject(recordOrEmpty(ordered.search.query_expansion),["enabled","provider"]),ordered.search.rerank=orderObject(recordOrEmpty(ordered.search.rerank),["enabled","model","top_k"]),ordered.providers=orderObject(ordered.providers,["openai","ollama"]),ordered.providers.openai=orderObject(recordOrEmpty(ordered.providers.openai),["base_url","api_key","model"]),ordered.providers.ollama=orderObject(recordOrEmpty(ordered.providers.ollama),["base_url","model"]),ordered.vector_store=orderObject(ordered.vector_store,["adapter","collection_name","qdrant","lancedb"]),ordered.vector_store.qdrant=orderObject(recordOrEmpty(ordered.vector_store.qdrant),["url","api_key"]),ordered.vector_store.lancedb=orderObject(recordOrEmpty(ordered.vector_store.lancedb),["path"])}function buildSerializeBaseSettings(settings){return{...settings,locks:valueOrDefault(settings.locks,SETTINGS_DEFAULTS.locks),ids:valueOrDefault(settings.ids,SETTINGS_DEFAULTS.ids),agent_identity:valueOrDefault(settings.agent_identity,SETTINGS_DEFAULTS.agent_identity),mutation_guard:valueOrDefault(settings.mutation_guard,SETTINGS_DEFAULTS.mutation_guard),checkpoints:valueOrDefault(settings.checkpoints,SETTINGS_DEFAULTS.checkpoints),output:valueOrDefault(settings.output,SETTINGS_DEFAULTS.output),ux:valueOrDefault(settings.ux,SETTINGS_DEFAULTS.ux),history:valueOrDefault(settings.history,SETTINGS_DEFAULTS.history),validation:valueOrDefault(settings.validation,SETTINGS_DEFAULTS.validation),workflow:valueOrDefault(settings.workflow,SETTINGS_DEFAULTS.workflow),testing:valueOrDefault(settings.testing,SETTINGS_DEFAULTS.testing),telemetry:valueOrDefault(settings.telemetry,SETTINGS_DEFAULTS.telemetry),agent_guidance:valueOrDefault(settings.agent_guidance,SETTINGS_DEFAULTS.agent_guidance),item_types:valueOrDefault(settings.item_types,SETTINGS_DEFAULTS.item_types),schema:valueOrDefault(settings.schema,SETTINGS_DEFAULTS.schema),context:valueOrDefault(settings.context,SETTINGS_DEFAULTS.context),extensions:valueOrDefault(settings.extensions,SETTINGS_DEFAULTS.extensions),search:valueOrDefault(settings.search,SETTINGS_DEFAULTS.search),providers:valueOrDefault(settings.providers,SETTINGS_DEFAULTS.providers),vector_store:valueOrDefault(settings.vector_store,SETTINGS_DEFAULTS.vector_store)}}function buildSerializedValidationSettings(baseSettings,governance){return{...baseSettings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(baseSettings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_stale_blocker_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_blocked_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_resolution_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_actual_result_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(baseSettings.validation?.estimate_defaults_by_type)}}function buildSerializedSearchSettings(baseSettings){return{...SETTINGS_DEFAULTS.search,...baseSettings.search,default_mode:normalizeSearchDefaultMode(baseSettings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(baseSettings.search?.mutation_refresh_policy),query_expansion:{...SETTINGS_DEFAULTS.search.query_expansion,...baseSettings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(baseSettings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(baseSettings.search?.query_expansion?.provider)},rerank:{...SETTINGS_DEFAULTS.search.rerank,...baseSettings.search?.rerank,enabled:normalizeSearchRerankEnabled(baseSettings.search?.rerank?.enabled),model:normalizeSearchRerankModel(baseSettings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(baseSettings.search?.rerank?.top_k)}}}function buildSerializedContextSettings(baseSettings){return{default_depth:baseSettings.context?.default_depth??SETTINGS_DEFAULTS.context.default_depth,activity_limit:baseSettings.context?.activity_limit??SETTINGS_DEFAULTS.context.activity_limit,stale_threshold_days:baseSettings.context?.stale_threshold_days??SETTINGS_DEFAULTS.context.stale_threshold_days,next_ranking_policy:baseSettings.context?.next_ranking_policy??SETTINGS_DEFAULTS.context.next_ranking_policy,sections:{...SETTINGS_DEFAULTS.context.sections,...baseSettings.context?.sections}}}function buildSerializedVectorStoreSettings(baseSettings){return{...baseSettings.vector_store,adapter:baseSettings.vector_store?.adapter??SETTINGS_DEFAULTS.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(baseSettings.vector_store?.collection_name),qdrant:{...baseSettings.vector_store?.qdrant},lancedb:{...baseSettings.vector_store?.lancedb}}}function buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections){return{...baseSettings,item_format:"toon",validation:buildSerializedValidationSettings(baseSettings,governance),governance,agent_guidance:normalizeAgentGuidanceSettings(baseSettings.agent_guidance),item_types:{definitions:persistedFileBackedSections.item_type_definitions},schema:{...normalizedSchema,statuses:persistedFileBackedSections.schema_statuses,fields:persistedFileBackedSections.schema_fields,type_workflows:persistedFileBackedSections.schema_type_workflows},search:buildSerializedSearchSettings(baseSettings),context:buildSerializedContextSettings(baseSettings),extensions:{enabled:normalizeStringList(baseSettings.extensions?.enabled),disabled:normalizeStringList(baseSettings.extensions?.disabled),policy:normalizeExtensionPolicySettings(baseSettings.extensions?.policy)},vector_store:buildSerializedVectorStoreSettings(baseSettings)}}function overlayPresentSettingsSource(target,source){for(const key of Object.keys(source)){const value=Reflect.get(source,key),existing=target[key];typeof value=="object"&&value!==null&&!Array.isArray(value)&&typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?overlayPresentSettingsSource(existing,value):target[key]=structuredClone(value)}}function applySettingsDelta(target,baseline,current){const keys=new Set([...Object.keys(baseline),...Object.keys(current)]);for(const key of keys){const before=baseline[key],after=current[key];if(!stableValueEquals(before,after)){if(after===void 0){delete target[key];continue}if(typeof before=="object"&&before!==null&&!Array.isArray(before)&&typeof after=="object"&&after!==null&&!Array.isArray(after)){const existing=target[key],nestedTarget=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?existing:{};applySettingsDelta(nestedTarget,before,after),Object.keys(nestedTarget).length>0?target[key]=nestedTarget:delete target[key];continue}target[key]=structuredClone(after)}}}const SETTINGS_TOP_LEVEL_KEY_ORDER=["version","id_prefix","ids","author_default","agent_identity","mutation_guard","item_format","locks","checkpoints","output","ux","history","validation","governance","workflow","testing","telemetry","agent_guidance","item_types","schema","context","extensions","search","providers","vector_store"];function buildOrderedSettingsForSerialization(settings,persistSource){const baseSettings=buildSerializeBaseSettings(settings),governance=resolveGovernanceKnobs(baseSettings),normalizedSchema=normalizeRuntimeSchemaSettings(baseSettings.schema),persistedFileBackedSections=resolvePersistedFileBackedSchemaSections(baseSettings,persistSource),normalizedSettings=buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections),ordered=orderObject({...normalizedSettings,governance:normalizeGovernanceForPersist(governance)},SETTINGS_TOP_LEVEL_KEY_ORDER);return orderSerializedSettingsSections(ordered),ordered}function serializeSettings(settings,options={}){const persistSource=options.source===void 0?options.persist_source:buildSettingsPersistSourceSnapshot(options.source.validated,mergeSettings(options.source.validated)),ordered=buildOrderedSettingsForSerialization(settings,persistSource);if(persistSource){const baselineSettings=mergeSettings(persistSource.source_settings);baselineSettings.item_types={definitions:structuredClone(persistSource.runtime_item_type_definitions)},baselineSettings.schema={...baselineSettings.schema,statuses:structuredClone(persistSource.runtime_schema_statuses),fields:structuredClone(persistSource.runtime_schema_fields),type_workflows:structuredClone(persistSource.runtime_schema_type_workflows)};const baseline=buildOrderedSettingsForSerialization(baselineSettings,persistSource);options.source!==void 0&&overlayPresentSettingsSource(baseline,options.source.validated);const sparse=structuredClone(options.source===void 0?persistSource.source_settings:options.source.raw);return applySettingsDelta(sparse,baseline,ordered),`${JSON.stringify(orderObject(sparse,SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
1
+ (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="aa89cd28-76a1-5eaf-b6f7-7501acefa5f2")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{lstat,realpath}from"node:fs/promises";import path from"node:path";import{CORE_SETTINGS_SECTION_KEYS,validateSettings}from"./settings-validator.js";import{runActiveOnReadHooks,runActiveOnWriteHooks}from"../extensions/index.js";import{EXIT_CODE,GOVERNANCE_PRESET_DEFAULTS,SETTINGS_DEFAULTS}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{resolveAuthor}from"../shared/author.js";import{isFileAbsentError,readFileIfExists,readRegularFile,transactionPreviewNonRegularFileError}from"../fs/fs-utils.js";import{mutateWorkspaceJsonWithHistory}from"../history/workspace-history.js";import{reconcileSettingsSnapshot}from"./settings-concurrency.js";import{DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,filePathForSchemaSection,loadRuntimeSchemaFromOptionalFiles,normalizeRuntimeSchemaSettings}from"../schema/runtime-schema.js";import{getSettingsPath}from"./paths.js";import{orderObject,stableValueEquals}from"../shared/serialization.js";import{normalizeItemTypeDefinition}from"../item/item-type-definition.js";import{normalizeEstimateDefaultOverrides}from"../validate/estimate-defaults.js";import{clearSettingsReadCache,collectSettingsReadCacheSignatures,getSettingsReadCacheEntry,setSettingsReadCacheEntry,settingsReadCacheSignaturesEqual}from"./settings-read-cache.js";import{GOVERNANCE_START_BLOCKER_ENFORCEMENT_VALUES}from"../../types/index.js";const configurationOnlySettingsRoots=new AsyncLocalStorage;async function runWithConfigurationOnlySettings(pmRoot,run,isEnabled=()=>!0){const roots=new Set([path.resolve(pmRoot)]);try{roots.add(await realpath(pmRoot))}catch{}return configurationOnlySettingsRoots.run([...configurationOnlySettingsRoots.getStore()??[],[roots,isEnabled]],run)}function isConfigurationOnlySettingsRead(pmRoot){const root=path.resolve(pmRoot);return configurationOnlySettingsRoots.getStore()?.some(([roots,isEnabled])=>roots.has(root)&&isEnabled())??!1}const SETTINGS_WRITE_OP="settings:write",SETTINGS_PERSIST_SOURCE_SYMBOL=Symbol("pm.settings.persist_source"),SETTINGS_FALLBACK_ORIGIN_SYMBOL=Symbol("pm.settings.fallback_origin"),SETTINGS_FALLBACK_BASELINE_SYMBOL=Symbol("pm.settings.fallback_baseline"),MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH=128,DUPLICATE_DETECTION_MODES=new Set(["off","advisory","strict"]);function resolveGovernanceKnobsFromPreset(preset){return structuredClone(GOVERNANCE_PRESET_DEFAULTS[preset])}function normalizeGovernancePreset(value){return value==="minimal"||value==="default"||value==="strict"||value==="custom"?value:SETTINGS_DEFAULTS.governance.preset}const START_BLOCKER_ENFORCEMENT_VALUES=new Set(GOVERNANCE_START_BLOCKER_ENFORCEMENT_VALUES);function isStartBlockerEnforcement(value){return START_BLOCKER_ENFORCEMENT_VALUES.has(value)}function withGovernanceExtras(base,governance){const createDefaultType=typeof governance.create_default_type=="string"?governance.create_default_type.trim():void 0;return createDefaultType&&createDefaultType.length>0&&(base.create_default_type=createDefaultType),(governance.workflow_enforcement==="off"||governance.workflow_enforcement==="warn"||governance.workflow_enforcement==="strict")&&(base.workflow_enforcement=governance.workflow_enforcement),isStartBlockerEnforcement(governance.start_blocker_enforcement)&&(base.start_blocker_enforcement=governance.start_blocker_enforcement),governance.require_close_reason===!1&&(base.require_close_reason=!1),base.duplicate_detection_mode=governance.duplicate_detection_mode,base.duplicate_detection_threshold=governance.duplicate_detection_threshold,base.duplicate_detection_limit=governance.duplicate_detection_limit,base}function normalizeGovernanceForPersist(governance){return governance.preset==="custom"?withGovernanceExtras({preset:"custom",ownership_enforcement:governance.ownership_enforcement,create_mode_default:governance.create_mode_default,close_validation_default:governance.close_validation_default,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,force_required_for_stale_lock:governance.force_required_for_stale_lock},governance):withGovernanceExtras({preset:governance.preset},governance)}function resolveGovernanceExtras(rawGovernance){const createDefaultType=typeof rawGovernance.create_default_type=="string"?rawGovernance.create_default_type.trim():void 0,extras={};createDefaultType&&createDefaultType.length>0&&(extras.create_default_type=createDefaultType),(rawGovernance.workflow_enforcement==="off"||rawGovernance.workflow_enforcement==="warn"||rawGovernance.workflow_enforcement==="strict")&&(extras.workflow_enforcement=rawGovernance.workflow_enforcement),isStartBlockerEnforcement(rawGovernance.start_blocker_enforcement)&&(extras.start_blocker_enforcement=rawGovernance.start_blocker_enforcement),typeof rawGovernance.require_close_reason=="boolean"&&(extras.require_close_reason=rawGovernance.require_close_reason),DUPLICATE_DETECTION_MODES.has(String(rawGovernance.duplicate_detection_mode))&&(extras.duplicate_detection_mode=rawGovernance.duplicate_detection_mode);const threshold=rawGovernance.duplicate_detection_threshold;[typeof threshold=="number",Number.isFinite(threshold),Number(threshold)>=0,Number(threshold)<=1].every(Boolean)&&(extras.duplicate_detection_threshold=threshold);const limit=rawGovernance.duplicate_detection_limit;return[typeof limit=="number",Number.isSafeInteger(limit),Number(limit)>=0,Number(limit)<=20].every(Boolean)&&(extras.duplicate_detection_limit=limit),extras}function resolveGovernanceKnobs(settings){const rawGovernance=settings.governance??{},preset=normalizeGovernancePreset(rawGovernance.preset),extras=resolveGovernanceExtras(rawGovernance);if(preset==="custom"){const baseline2=resolveGovernanceKnobsFromPreset("default"),requireCloseReason2=extras.require_close_reason??baseline2.require_close_reason;return{preset,ownership_enforcement:rawGovernance.ownership_enforcement??baseline2.ownership_enforcement,create_mode_default:rawGovernance.create_mode_default??baseline2.create_mode_default,close_validation_default:rawGovernance.close_validation_default??baseline2.close_validation_default,parent_reference:rawGovernance.parent_reference??baseline2.parent_reference,metadata_profile:rawGovernance.metadata_profile??baseline2.metadata_profile,force_required_for_stale_lock:rawGovernance.force_required_for_stale_lock??baseline2.force_required_for_stale_lock,...extras,require_close_reason:requireCloseReason2,duplicate_detection_mode:extras.duplicate_detection_mode??baseline2.duplicate_detection_mode,duplicate_detection_threshold:extras.duplicate_detection_threshold??baseline2.duplicate_detection_threshold,duplicate_detection_limit:extras.duplicate_detection_limit??baseline2.duplicate_detection_limit}}const baseline=resolveGovernanceKnobsFromPreset(preset),requireCloseReason=extras.require_close_reason??baseline.require_close_reason;return{preset,...baseline,...extras,require_close_reason:requireCloseReason}}function cloneDefaults(){return structuredClone(SETTINGS_DEFAULTS)}function normalizeSearchMutationRefreshPolicy(value){return value==="cache_only"||value==="semantic_configured"||value==="semantic_auto"?value:SETTINGS_DEFAULTS.search.mutation_refresh_policy}function normalizeSearchDefaultMode(value){return value==="auto"||value==="keyword"||value==="semantic"||value==="hybrid"?value:"auto"}function normalizeSearchQueryExpansionEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.query_expansion.enabled}function normalizeSearchQueryExpansionProvider(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.query_expansion.provider:value.trim()}function normalizeSearchRerankEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.rerank.enabled}function normalizeSearchRerankModel(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.rerank.model:value.trim()}function normalizeSearchRerankTopK(value){return typeof value=="number"&&Number.isFinite(value)&&Number.isInteger(value)&&value>0?value:SETTINGS_DEFAULTS.search.rerank.top_k}function normalizeVectorStoreCollectionName(value){if(typeof value!="string")return SETTINGS_DEFAULTS.vector_store.collection_name;const truncated=value.trim().replaceAll(/[^a-zA-Z0-9_-]/g,"_").slice(0,MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH);return truncated.length>0?truncated:SETTINGS_DEFAULTS.vector_store.collection_name}function cloneOptionalArray(value){return{present:Array.isArray(value),values:Array.isArray(value)?structuredClone(value):[]}}function buildSettingsPersistSourceSnapshot(parsedSettings,runtimeSettings){const sourceSchema=parsedSettings.schema,sourceStatuses=cloneOptionalArray(sourceSchema?.statuses),sourceFields=cloneOptionalArray(sourceSchema?.fields),sourceTypeWorkflows=cloneOptionalArray(sourceSchema?.type_workflows);return{persisted_settings:structuredClone(parsedSettings),source_settings:structuredClone(parsedSettings),has_source_item_type_definitions:Array.isArray(parsedSettings.item_types?.definitions),source_item_type_definitions:normalizeItemTypeDefinitions(parsedSettings.item_types?.definitions),has_source_schema_statuses:sourceStatuses.present,source_schema_statuses:sourceStatuses.values,has_source_schema_fields:sourceFields.present,source_schema_fields:sourceFields.values,has_source_schema_type_workflows:sourceTypeWorkflows.present,source_schema_type_workflows:sourceTypeWorkflows.values,runtime_item_type_definitions:normalizeItemTypeDefinitions(runtimeSettings.item_types?.definitions),runtime_schema_statuses:structuredClone(runtimeSettings.schema.statuses),runtime_schema_fields:structuredClone(runtimeSettings.schema.fields),runtime_schema_type_workflows:structuredClone(runtimeSettings.schema.type_workflows??[])}}function attachSettingsPersistSourceSnapshot(settings,source){Object.defineProperty(settings,SETTINGS_PERSIST_SOURCE_SYMBOL,{value:source,writable:!0,configurable:!0,enumerable:!1})}function getSettingsPersistSourceSnapshot(settings){const candidate=settings[SETTINGS_PERSIST_SOURCE_SYMBOL];if(!(!candidate||typeof candidate!="object"))return candidate}function persistSelectedItemFormat(settings){const source=getSettingsPersistSourceSnapshot(settings);if(source){const detachedSource=structuredClone(source);detachedSource.source_settings.item_format=settings.item_format,attachSettingsPersistSourceSnapshot(settings,detachedSource)}}function cloneSettingsReadResult(result){const clonedSettings=structuredClone(result.settings),persistSource=getSettingsPersistSourceSnapshot(result.settings);persistSource&&attachSettingsPersistSourceSnapshot(clonedSettings,persistSource);const fallbackOrigin=getSettingsFallbackOrigin(result.settings);return fallbackOrigin!==void 0&&markSettingsFallbackOrigin(clonedSettings,fallbackOrigin),{settings:clonedSettings,metadata:{has_explicit_item_format:result.metadata.has_explicit_item_format},warnings:[...result.warnings]}}function resolveSettingsReadTrackedPaths(pmRoot,schema,settingsPath){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);return[settingsPath,filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types),filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses),filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields),filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows)]}async function cacheSettingsReadResult(pmRoot,trackedPaths,result){const signatures=await collectSettingsReadCacheSignatures(trackedPaths);setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures,value:cloneSettingsReadResult(result)})}async function cacheSettingsReadResultSafe(pmRoot,trackedPaths,result){try{await cacheSettingsReadResult(pmRoot,trackedPaths,result)}catch{clearSettingsReadCache(pmRoot)}}function findSettingsReadCacheSignature(signatures,targetPath){return signatures.find(signature=>signature.path===targetPath)}function selectedSettingsReadCacheSignaturesEqual(before,after,targetPaths){for(const targetPath of targetPaths){const beforeSignature=findSettingsReadCacheSignature(before,targetPath),afterSignature=findSettingsReadCacheSignature(after,targetPath);if(!beforeSignature||!afterSignature||!settingsReadCacheSignaturesEqual([beforeSignature],[afterSignature]))return!1}return!0}async function cacheSettingsReadResultIfStable(pmRoot,trackedPaths,result,stableSignatures,stablePaths){try{const currentSignatures=await collectSettingsReadCacheSignatures(trackedPaths);if(!selectedSettingsReadCacheSignaturesEqual(stableSignatures,currentSignatures,stablePaths)){clearSettingsReadCache(pmRoot);return}setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:currentSignatures,value:cloneSettingsReadResult(result)})}catch{clearSettingsReadCache(pmRoot)}}function resolvePersistedFileBackedSchemaSections(settings,source){const normalizedSchema=normalizeRuntimeSchemaSettings(settings.schema),currentItemTypeDefinitions=normalizeItemTypeDefinitions(settings.item_types?.definitions);if(!source)return{item_type_definitions:currentItemTypeDefinitions,schema_statuses:normalizedSchema.statuses,schema_fields:normalizedSchema.fields,schema_type_workflows:normalizedSchema.type_workflows};const currentTypeWorkflows=normalizedSchema.type_workflows??[],itemTypeDefinitionsUnchanged=stableValueEquals(currentItemTypeDefinitions,source.runtime_item_type_definitions),schemaStatusesUnchanged=stableValueEquals(normalizedSchema.statuses,source.runtime_schema_statuses),schemaFieldsUnchanged=stableValueEquals(normalizedSchema.fields,source.runtime_schema_fields),schemaTypeWorkflowsUnchanged=stableValueEquals(currentTypeWorkflows,source.runtime_schema_type_workflows);return{item_type_definitions:itemTypeDefinitionsUnchanged?source.has_source_item_type_definitions?normalizeItemTypeDefinitions(source.source_item_type_definitions):[]:currentItemTypeDefinitions,schema_statuses:schemaStatusesUnchanged?source.has_source_schema_statuses?structuredClone(source.source_schema_statuses):[]:normalizedSchema.statuses,schema_fields:schemaFieldsUnchanged?source.has_source_schema_fields?structuredClone(source.source_schema_fields):[]:normalizedSchema.fields,schema_type_workflows:schemaTypeWorkflowsUnchanged?source.has_source_schema_type_workflows?structuredClone(source.source_schema_type_workflows):void 0:normalizedSchema.type_workflows}}function markSettingsFallbackOrigin(settings,warning){Object.defineProperty(settings,SETTINGS_FALLBACK_ORIGIN_SYMBOL,{value:warning,writable:!0,configurable:!0,enumerable:!1})}function isSettingsReadFallback(settings){return getSettingsFallbackOrigin(settings)!==void 0}function getSettingsFallbackOrigin(settings){const candidate=settings[SETTINGS_FALLBACK_ORIGIN_SYMBOL];return typeof candidate=="string"?candidate:void 0}function getSettingsFallbackBaseline(settings){return settings[SETTINGS_FALLBACK_BASELINE_SYMBOL]}function setSettingsFallbackBaseline(settings,baseline){Object.defineProperty(settings,SETTINGS_FALLBACK_BASELINE_SYMBOL,{value:baseline,writable:!0,configurable:!0,enumerable:!1})}function buildFallbackSettingsReadResult(warning){const settings=cloneDefaults();return warning!==void 0&&markSettingsFallbackOrigin(settings,warning),{settings,metadata:{has_explicit_item_format:!1},warnings:warning?[warning]:[]}}function hasExplicitItemFormat(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return!1;const itemFormat=raw.item_format;return itemFormat==="toon"||itemFormat==="json_markdown"}function normalizeStringList(values){return[...new Set((values??[]).map(value=>value.trim()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeAgentGuidanceSettings(value){const defaults=SETTINGS_DEFAULTS.agent_guidance,templateVersion=value?.template_version;return{prompt_completed:value?.prompt_completed===!0,declined:value?.declined===!0,declined_at:typeof value?.declined_at=="string"?value.declined_at:defaults.declined_at,template_version:typeof templateVersion=="number"&&Number.isInteger(templateVersion)&&templateVersion>0?templateVersion:defaults.template_version,last_checked_files:normalizeStringList(value?.last_checked_files??defaults.last_checked_files)}}function normalizeLowerStringList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeExtensionPolicyMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.mode}function normalizeExtensionTrustMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.trust_mode}function normalizeExtensionSandboxProfile(value){return value==="none"||value==="restricted"||value==="strict"?value:SETTINGS_DEFAULTS.extensions.policy.default_sandbox_profile}function normalizeExtensionPolicyOverride(override){const name=override.name.trim().toLowerCase();if(name.length===0)return null;const normalized={name};override.disabled===!0&&(normalized.disabled=!0),override.require_trusted===!0&&(normalized.require_trusted=!0),override.require_provenance===!0&&(normalized.require_provenance=!0),override.sandbox_profile!==void 0&&(normalized.sandbox_profile=normalizeExtensionSandboxProfile(override.sandbox_profile));const allowedCapabilities=normalizeLowerStringList(override.allowed_capabilities),blockedCapabilities=normalizeLowerStringList(override.blocked_capabilities),allowedSurfaces=normalizeLowerStringList(override.allowed_surfaces),blockedSurfaces=normalizeLowerStringList(override.blocked_surfaces),allowedCommands=normalizeLowerStringList(override.allowed_commands),blockedCommands=normalizeLowerStringList(override.blocked_commands),allowedActions=normalizeLowerStringList(override.allowed_actions),blockedActions=normalizeLowerStringList(override.blocked_actions),allowedServices=normalizeLowerStringList(override.allowed_services),blockedServices=normalizeLowerStringList(override.blocked_services);return allowedCapabilities.length>0&&(normalized.allowed_capabilities=allowedCapabilities),blockedCapabilities.length>0&&(normalized.blocked_capabilities=blockedCapabilities),allowedSurfaces.length>0&&(normalized.allowed_surfaces=allowedSurfaces),blockedSurfaces.length>0&&(normalized.blocked_surfaces=blockedSurfaces),allowedCommands.length>0&&(normalized.allowed_commands=allowedCommands),blockedCommands.length>0&&(normalized.blocked_commands=blockedCommands),allowedActions.length>0&&(normalized.allowed_actions=allowedActions),blockedActions.length>0&&(normalized.blocked_actions=blockedActions),allowedServices.length>0&&(normalized.allowed_services=allowedServices),blockedServices.length>0&&(normalized.blocked_services=blockedServices),normalized}function normalizeExtensionPolicyOverrides(overrides){const dedupedByName=new Map;for(const override of overrides??[]){const normalized=normalizeExtensionPolicyOverride(override);normalized&&dedupedByName.set(normalized.name,normalized)}return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function normalizePmMaxVersionExceededModeValue(value){return value==="block"||value==="warn"?value:void 0}function normalizePmMaxVersionExceededModeSetting(value){if(typeof value=="string")return normalizePmMaxVersionExceededModeValue(value);if(typeof value=="object"&&value!==null&&!Array.isArray(value)){const global2=normalizePmMaxVersionExceededModeValue(value.global),project=normalizePmMaxVersionExceededModeValue(value.project);return global2===void 0&&project===void 0?void 0:{...global2!==void 0?{global:global2}:{},...project!==void 0?{project}:{}}}}function normalizeExtensionPolicyList(policy,key){return normalizeLowerStringList(policy?.[key]??SETTINGS_DEFAULTS.extensions.policy[key])}function normalizeExtensionPolicySettings(policy){const pmMaxVersionExceededMode=normalizePmMaxVersionExceededModeSetting(policy?.pm_max_version_exceeded_mode);return{mode:normalizeExtensionPolicyMode(policy?.mode),trust_mode:normalizeExtensionTrustMode(policy?.trust_mode),...pmMaxVersionExceededMode!==void 0?{pm_max_version_exceeded_mode:pmMaxVersionExceededMode}:{},require_provenance:policy?.require_provenance===!0,trusted_extensions:normalizeExtensionPolicyList(policy,"trusted_extensions"),default_sandbox_profile:normalizeExtensionSandboxProfile(policy?.default_sandbox_profile),allowed_extensions:normalizeExtensionPolicyList(policy,"allowed_extensions"),blocked_extensions:normalizeExtensionPolicyList(policy,"blocked_extensions"),allowed_capabilities:normalizeExtensionPolicyList(policy,"allowed_capabilities"),blocked_capabilities:normalizeExtensionPolicyList(policy,"blocked_capabilities"),allowed_surfaces:normalizeExtensionPolicyList(policy,"allowed_surfaces"),blocked_surfaces:normalizeExtensionPolicyList(policy,"blocked_surfaces"),allowed_commands:normalizeExtensionPolicyList(policy,"allowed_commands"),blocked_commands:normalizeExtensionPolicyList(policy,"blocked_commands"),allowed_actions:normalizeExtensionPolicyList(policy,"allowed_actions"),blocked_actions:normalizeExtensionPolicyList(policy,"blocked_actions"),allowed_services:normalizeExtensionPolicyList(policy,"allowed_services"),blocked_services:normalizeExtensionPolicyList(policy,"blocked_services"),extension_overrides:normalizeExtensionPolicyOverrides(policy?.extension_overrides??SETTINGS_DEFAULTS.extensions.policy.extension_overrides)}}function normalizeValidationMetadataRequiredFields(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase().replaceAll("-","_")))].filter(value=>value.length>0).sort((left,right)=>left.localeCompare(right)).filter(value=>["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"].includes(value))}function normalizeValidationPatternList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function valueOrDefault(value,fallback){return value===void 0?fallback:value}function recordOrEmpty(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:{}}function arrayOrEmpty(value){return Array.isArray(value)?value:[]}function buildValidationSettings(settings,defaults,governance){return{...defaults.validation,...settings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(settings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_stale_blocker_reason_patterns??defaults.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_blocked_reason_patterns??defaults.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_resolution_patterns??defaults.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_actual_result_patterns??defaults.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(settings.validation?.estimate_defaults_by_type)}}function buildTelemetrySettings(settings,defaults){return{enabled:settings.telemetry?.enabled??defaults.telemetry.enabled,first_run_prompt_completed:settings.telemetry?.first_run_prompt_completed??defaults.telemetry.first_run_prompt_completed,capture_level:settings.telemetry?.capture_level??defaults.telemetry.capture_level,endpoint:settings.telemetry?.endpoint??defaults.telemetry.endpoint,installation_id:settings.telemetry?.installation_id??defaults.telemetry.installation_id,retention_days:settings.telemetry?.retention_days??defaults.telemetry.retention_days}}function buildSearchSettings(settings,defaults){return{...defaults.search,...settings.search,default_mode:normalizeSearchDefaultMode(settings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(settings.search?.mutation_refresh_policy),query_expansion:{...defaults.search.query_expansion,...settings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(settings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(settings.search?.query_expansion?.provider)},rerank:{...defaults.search.rerank,...settings.search?.rerank,enabled:normalizeSearchRerankEnabled(settings.search?.rerank?.enabled),model:normalizeSearchRerankModel(settings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(settings.search?.rerank?.top_k)}}}function buildVectorStoreSettings(settings,defaults){return{adapter:settings.vector_store.adapter??defaults.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(settings.vector_store.collection_name),qdrant:{...defaults.vector_store.qdrant,...settings.vector_store.qdrant},lancedb:{...defaults.vector_store.lancedb,...settings.vector_store.lancedb}}}function normalizeSettingsItemFormat(settings,defaults){return settings.item_format==="json_markdown"?"toon":settings.item_format??defaults.item_format}function buildContextSettings(settings,defaults){return{default_depth:settings.context?.default_depth??defaults.context.default_depth,activity_limit:settings.context?.activity_limit??defaults.context.activity_limit,stale_threshold_days:settings.context?.stale_threshold_days??defaults.context.stale_threshold_days,next_ranking_policy:settings.context?.next_ranking_policy??defaults.context.next_ranking_policy,sections:{...defaults.context.sections,...settings.context?.sections}}}function buildProviderSettings(settings,defaults){return{openai:{...defaults.providers.openai,...settings.providers.openai},ollama:{...defaults.providers.ollama,...settings.providers.ollama}}}function normalizeItemTypeDefinitions(definitions){const normalized=(definitions??[]).map(definition=>normalizeItemTypeDefinition(definition)).filter(definition=>definition!==null),dedupedByName=new Map;for(const definition of normalized)dedupedByName.set(definition.name.toLowerCase(),definition);return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function mergeSettings(settings){const defaults=cloneDefaults(),governance=resolveGovernanceKnobs({governance:settings.governance??{preset:"default"}});return{...defaults,...settings,item_format:normalizeSettingsItemFormat(settings,defaults),locks:{...defaults.locks,...settings.locks},ids:{...defaults.ids,...settings.ids},agent_identity:structuredClone(settings.agent_identity??defaults.agent_identity),mutation_guard:{...defaults.mutation_guard,...settings.mutation_guard},checkpoints:{...defaults.checkpoints,...settings.checkpoints},output:{...defaults.output,...settings.output},ux:{...defaults.ux,...settings.ux},history:{...defaults.history,...settings.history,compact_policy:{...defaults.history.compact_policy,...settings.history?.compact_policy}},validation:buildValidationSettings(settings,defaults,governance),governance,workflow:{definition_of_done:[...settings.workflow?.definition_of_done??defaults.workflow.definition_of_done]},testing:{record_results_to_items:settings.testing?.record_results_to_items??defaults.testing.record_results_to_items,allow_untrusted_linked_tests:settings.testing?.allow_untrusted_linked_tests??defaults.testing.allow_untrusted_linked_tests},telemetry:buildTelemetrySettings(settings,defaults),agent_guidance:normalizeAgentGuidanceSettings(settings.agent_guidance??defaults.agent_guidance),item_types:{definitions:normalizeItemTypeDefinitions(settings.item_types?.definitions)},schema:normalizeRuntimeSchemaSettings(settings.schema??defaults.schema),context:buildContextSettings(settings,defaults),extensions:{enabled:[...settings.extensions.enabled],disabled:[...settings.extensions.disabled],policy:normalizeExtensionPolicySettings(settings.extensions.policy??defaults.extensions.policy)},search:buildSearchSettings(settings,defaults),providers:buildProviderSettings(settings,defaults),vector_store:buildVectorStoreSettings(settings,defaults)}}function orderSerializedSettingsSections(ordered){ordered.agent_identity=orderObject(ordered.agent_identity,["probes_enabled","identity_vocabulary","harness_signals"]);const orderedAgentIdentity=ordered.agent_identity;Object.hasOwn(orderedAgentIdentity,"identity_vocabulary")&&(orderedAgentIdentity.identity_vocabulary=orderObject(recordOrEmpty(orderedAgentIdentity.identity_vocabulary),["version","aliases"])),ordered.agent_identity.harness_signals=arrayOrEmpty(ordered.agent_identity.harness_signals).map(entry=>orderObject(recordOrEmpty(entry),["harness","environment_keys","model_environment_keys","session_environment_keys","provenance_environment_keys","provenance_resolvers","provenance_unavailable_dimensions","argv_markers","client_names"])),ordered.locks=orderObject(ordered.locks,["ttl_seconds","wait_ms"]),ordered.ids=orderObject(ordered.ids,["token_length"]),ordered.mutation_guard=orderObject(ordered.mutation_guard,["require_attributed_author","secret_guard","stale_in_progress_hours"]),ordered.checkpoints=orderObject(ordered.checkpoints,["retention_days"]),ordered.output=orderObject(ordered.output,["default_format"]),ordered.ux=orderObject(ordered.ux,["deprecation_hints"]),ordered.history=orderObject(ordered.history,["missing_stream","compact_policy"]),ordered.validation=orderObject(ordered.validation,["sprint_release_format","parent_reference","metadata_profile","metadata_required_fields","lifecycle_stale_blocker_reason_patterns","lifecycle_closure_like_blocked_reason_patterns","lifecycle_closure_like_resolution_patterns","lifecycle_closure_like_actual_result_patterns","estimate_defaults_by_type"]),ordered.governance=orderObject(ordered.governance,["preset","ownership_enforcement","create_mode_default","close_validation_default","require_close_reason","parent_reference","metadata_profile","force_required_for_stale_lock","create_default_type","workflow_enforcement","duplicate_detection_mode","duplicate_detection_threshold","duplicate_detection_limit"]),ordered.workflow=orderObject(ordered.workflow,["definition_of_done"]),ordered.testing=orderObject(ordered.testing,["record_results_to_items","allow_untrusted_linked_tests"]),ordered.telemetry=orderObject(ordered.telemetry,["enabled","first_run_prompt_completed","capture_level","endpoint","installation_id","retention_days"]),ordered.agent_guidance=orderObject(ordered.agent_guidance,["prompt_completed","declined","declined_at","template_version","last_checked_files"]),ordered.item_types=orderObject(ordered.item_types,["definitions"]),ordered.schema=orderObject(ordered.schema,["version","files","statuses","fields","workflow","type_workflows","unknown_field_policy"]),ordered.schema.files=orderObject(recordOrEmpty(ordered.schema.files),["types","statuses","fields","workflows"]),ordered.schema.workflow=orderObject(recordOrEmpty(ordered.schema.workflow),["draft_status","open_status","in_progress_status","blocked_status","close_status","canceled_status"]),ordered.context=orderObject(ordered.context,["default_depth","activity_limit","stale_threshold_days","next_ranking_policy","sections"]),ordered.context.sections=orderObject(recordOrEmpty(ordered.context.sections),["hierarchy","activity","progress","blockers","files","workload","staleness","tests"]),ordered.extensions=orderObject(ordered.extensions,["enabled","disabled","policy"]),ordered.extensions.policy=orderObject(recordOrEmpty(ordered.extensions.policy),["mode","trust_mode","pm_max_version_exceeded_mode","require_provenance","trusted_extensions","default_sandbox_profile","allowed_extensions","blocked_extensions","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services","extension_overrides"]),ordered.extensions.policy.extension_overrides=arrayOrEmpty(ordered.extensions.policy.extension_overrides).map(entry=>orderObject(recordOrEmpty(entry),["name","disabled","require_trusted","require_provenance","sandbox_profile","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"])),ordered.search=orderObject(ordered.search,["score_threshold","hybrid_semantic_weight","max_results","embedding_model","embedding_corpus_max_characters","embedding_batch_size","embedding_timeout_ms","scanner_max_batch_retries","provider","default_mode","mutation_refresh_policy","query_expansion","rerank"]),ordered.search.query_expansion=orderObject(recordOrEmpty(ordered.search.query_expansion),["enabled","provider"]),ordered.search.rerank=orderObject(recordOrEmpty(ordered.search.rerank),["enabled","model","top_k"]),ordered.providers=orderObject(ordered.providers,["openai","ollama"]),ordered.providers.openai=orderObject(recordOrEmpty(ordered.providers.openai),["base_url","api_key","model"]),ordered.providers.ollama=orderObject(recordOrEmpty(ordered.providers.ollama),["base_url","model"]),ordered.vector_store=orderObject(ordered.vector_store,["adapter","collection_name","qdrant","lancedb"]),ordered.vector_store.qdrant=orderObject(recordOrEmpty(ordered.vector_store.qdrant),["url","api_key"]),ordered.vector_store.lancedb=orderObject(recordOrEmpty(ordered.vector_store.lancedb),["path"])}function buildSerializeBaseSettings(settings){return{...settings,locks:valueOrDefault(settings.locks,SETTINGS_DEFAULTS.locks),ids:valueOrDefault(settings.ids,SETTINGS_DEFAULTS.ids),agent_identity:valueOrDefault(settings.agent_identity,SETTINGS_DEFAULTS.agent_identity),mutation_guard:valueOrDefault(settings.mutation_guard,SETTINGS_DEFAULTS.mutation_guard),checkpoints:valueOrDefault(settings.checkpoints,SETTINGS_DEFAULTS.checkpoints),output:valueOrDefault(settings.output,SETTINGS_DEFAULTS.output),ux:valueOrDefault(settings.ux,SETTINGS_DEFAULTS.ux),history:valueOrDefault(settings.history,SETTINGS_DEFAULTS.history),validation:valueOrDefault(settings.validation,SETTINGS_DEFAULTS.validation),workflow:valueOrDefault(settings.workflow,SETTINGS_DEFAULTS.workflow),testing:valueOrDefault(settings.testing,SETTINGS_DEFAULTS.testing),telemetry:valueOrDefault(settings.telemetry,SETTINGS_DEFAULTS.telemetry),agent_guidance:valueOrDefault(settings.agent_guidance,SETTINGS_DEFAULTS.agent_guidance),item_types:valueOrDefault(settings.item_types,SETTINGS_DEFAULTS.item_types),schema:valueOrDefault(settings.schema,SETTINGS_DEFAULTS.schema),context:valueOrDefault(settings.context,SETTINGS_DEFAULTS.context),extensions:valueOrDefault(settings.extensions,SETTINGS_DEFAULTS.extensions),search:valueOrDefault(settings.search,SETTINGS_DEFAULTS.search),providers:valueOrDefault(settings.providers,SETTINGS_DEFAULTS.providers),vector_store:valueOrDefault(settings.vector_store,SETTINGS_DEFAULTS.vector_store)}}function buildSerializedValidationSettings(baseSettings,governance){return{...baseSettings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(baseSettings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_stale_blocker_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_blocked_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_resolution_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_actual_result_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(baseSettings.validation?.estimate_defaults_by_type)}}function buildSerializedSearchSettings(baseSettings){return{...SETTINGS_DEFAULTS.search,...baseSettings.search,default_mode:normalizeSearchDefaultMode(baseSettings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(baseSettings.search?.mutation_refresh_policy),query_expansion:{...SETTINGS_DEFAULTS.search.query_expansion,...baseSettings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(baseSettings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(baseSettings.search?.query_expansion?.provider)},rerank:{...SETTINGS_DEFAULTS.search.rerank,...baseSettings.search?.rerank,enabled:normalizeSearchRerankEnabled(baseSettings.search?.rerank?.enabled),model:normalizeSearchRerankModel(baseSettings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(baseSettings.search?.rerank?.top_k)}}}function buildSerializedContextSettings(baseSettings){return{default_depth:baseSettings.context?.default_depth??SETTINGS_DEFAULTS.context.default_depth,activity_limit:baseSettings.context?.activity_limit??SETTINGS_DEFAULTS.context.activity_limit,stale_threshold_days:baseSettings.context?.stale_threshold_days??SETTINGS_DEFAULTS.context.stale_threshold_days,next_ranking_policy:baseSettings.context?.next_ranking_policy??SETTINGS_DEFAULTS.context.next_ranking_policy,sections:{...SETTINGS_DEFAULTS.context.sections,...baseSettings.context?.sections}}}function buildSerializedVectorStoreSettings(baseSettings){return{...baseSettings.vector_store,adapter:baseSettings.vector_store?.adapter??SETTINGS_DEFAULTS.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(baseSettings.vector_store?.collection_name),qdrant:{...baseSettings.vector_store?.qdrant},lancedb:{...baseSettings.vector_store?.lancedb}}}function buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections){return{...baseSettings,item_format:"toon",validation:buildSerializedValidationSettings(baseSettings,governance),governance,agent_guidance:normalizeAgentGuidanceSettings(baseSettings.agent_guidance),item_types:{definitions:persistedFileBackedSections.item_type_definitions},schema:{...normalizedSchema,statuses:persistedFileBackedSections.schema_statuses,fields:persistedFileBackedSections.schema_fields,type_workflows:persistedFileBackedSections.schema_type_workflows},search:buildSerializedSearchSettings(baseSettings),context:buildSerializedContextSettings(baseSettings),extensions:{enabled:normalizeStringList(baseSettings.extensions?.enabled),disabled:normalizeStringList(baseSettings.extensions?.disabled),policy:normalizeExtensionPolicySettings(baseSettings.extensions?.policy)},vector_store:buildSerializedVectorStoreSettings(baseSettings)}}function overlayPresentSettingsSource(target,source){for(const key of Object.keys(source)){const value=Reflect.get(source,key),existing=target[key];typeof value=="object"&&value!==null&&!Array.isArray(value)&&typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?overlayPresentSettingsSource(existing,value):target[key]=structuredClone(value)}}function applySettingsDelta(target,baseline,current){const keys=new Set([...Object.keys(baseline),...Object.keys(current)]);for(const key of keys){const before=baseline[key],after=current[key];if(!stableValueEquals(before,after)){if(after===void 0){delete target[key];continue}if(typeof before=="object"&&before!==null&&!Array.isArray(before)&&typeof after=="object"&&after!==null&&!Array.isArray(after)){const existing=target[key],nestedTarget=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?existing:{};applySettingsDelta(nestedTarget,before,after),Object.keys(nestedTarget).length>0?target[key]=nestedTarget:delete target[key];continue}target[key]=structuredClone(after)}}}const SETTINGS_TOP_LEVEL_KEY_ORDER=["version","id_prefix","ids","author_default","agent_identity","mutation_guard","item_format","locks","checkpoints","output","ux","history","validation","governance","workflow","testing","telemetry","agent_guidance","item_types","schema","context","extensions","search","providers","vector_store"];function buildOrderedSettingsForSerialization(settings,persistSource){const baseSettings=buildSerializeBaseSettings(settings),governance=resolveGovernanceKnobs(baseSettings),normalizedSchema=normalizeRuntimeSchemaSettings(baseSettings.schema),persistedFileBackedSections=resolvePersistedFileBackedSchemaSections(baseSettings,persistSource),normalizedSettings=buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections),ordered=orderObject({...normalizedSettings,governance:normalizeGovernanceForPersist(governance)},SETTINGS_TOP_LEVEL_KEY_ORDER);return orderSerializedSettingsSections(ordered),ordered}function serializeSettings(settings,options={}){const persistSource=options.source===void 0?options.persist_source:buildSettingsPersistSourceSnapshot(options.source.validated,mergeSettings(options.source.validated)),ordered=buildOrderedSettingsForSerialization(settings,persistSource);if(persistSource){const baselineSettings=mergeSettings(persistSource.source_settings);baselineSettings.item_types={definitions:structuredClone(persistSource.runtime_item_type_definitions)},baselineSettings.schema={...baselineSettings.schema,statuses:structuredClone(persistSource.runtime_schema_statuses),fields:structuredClone(persistSource.runtime_schema_fields),type_workflows:structuredClone(persistSource.runtime_schema_type_workflows)};const baseline=buildOrderedSettingsForSerialization(baselineSettings,persistSource);options.source!==void 0&&overlayPresentSettingsSource(baseline,options.source.validated);const sparse=structuredClone(options.source===void 0?persistSource.source_settings:options.source.raw);return applySettingsDelta(sparse,baseline,ordered),`${JSON.stringify(orderObject(sparse,SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
2
2
  `}return`${JSON.stringify(ordered,null,2)}
3
3
  `}async function readConfigurationOnlySettings(pmRoot){let root;try{root=await realpath(pmRoot)}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}const file=getSettingsPath(root);let entry;try{entry=await lstat(file)}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}if(!entry.isFile())throw transactionPreviewNonRegularFileError("settings.json");let raw;try{raw=await readRegularFile(file,transactionPreviewNonRegularFileError("settings.json"))}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}let parsed;try{parsed=JSON.parse(raw)}catch{return buildFallbackSettingsReadResult("settings_read_invalid_json")}const validated=validateSettings(parsed);return validated.success?{settings:mergeSettings(validated.data),metadata:{has_explicit_item_format:hasExplicitItemFormat(parsed)},warnings:validated.data.item_format==="json_markdown"?["settings_item_format_legacy_json_markdown_coerced_to_toon"]:[]}:buildFallbackSettingsReadResult("settings_read_invalid_schema")}async function readSettingsWithMetadata(pmRoot){if(isConfigurationOnlySettingsRead(pmRoot))return readConfigurationOnlySettings(pmRoot);const settingsPath=getSettingsPath(pmRoot);let trackedPathsForFailure=[settingsPath];await runActiveOnReadHooks({path:settingsPath,scope:"project"});const cachedResult=getSettingsReadCacheEntry(pmRoot);if(cachedResult){const currentSignatures=await collectSettingsReadCacheSignatures(cachedResult.tracked_paths);if(settingsReadCacheSignaturesEqual(currentSignatures,cachedResult.signatures))return cloneSettingsReadResult(cachedResult.value)}const settingsOnlySignatures=await collectSettingsReadCacheSignatures([settingsPath]);let raw;try{raw=await readFileIfExists(settingsPath)}catch{return buildFallbackSettingsReadResult("settings_read_fs_error")}if(raw===null){const fallback=buildFallbackSettingsReadResult();return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsOnlySignatures,[settingsPath]),fallback}const settingsSignaturesAfterRead=await collectSettingsReadCacheSignatures([settingsPath]);if(!settingsReadCacheSignaturesEqual(settingsOnlySignatures,settingsSignaturesAfterRead))return clearSettingsReadCache(pmRoot),readSettingsWithMetadata(pmRoot);let parsed;try{parsed=JSON.parse(raw)}catch{const fallback=buildFallbackSettingsReadResult("settings_read_invalid_json");return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsSignaturesAfterRead,[settingsPath]),fallback}const validated=validateSettings(parsed);if(!validated.success){const fallback=buildFallbackSettingsReadResult("settings_read_invalid_schema");return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsSignaturesAfterRead,[settingsPath]),fallback}try{const mergedSettings=mergeSettings(validated.data),trackedPaths=resolveSettingsReadTrackedPaths(pmRoot,mergedSettings.schema,settingsPath);trackedPathsForFailure=trackedPaths;const signaturesBeforeSchemaLoad=await collectSettingsReadCacheSignatures(trackedPaths),loadedSchemaSections=await loadRuntimeSchemaFromOptionalFiles(pmRoot,mergedSettings.schema),signaturesAfterSchemaLoad=await collectSettingsReadCacheSignatures(trackedPaths),settings={...mergedSettings,item_types:{definitions:normalizeItemTypeDefinitions([...mergedSettings.item_types.definitions,...arrayOrEmpty(loadedSchemaSections.type_definitions_from_file)])},schema:loadedSchemaSections.schema};attachSettingsPersistSourceSnapshot(settings,buildSettingsPersistSourceSnapshot(validated.data,settings));const result={settings,metadata:{has_explicit_item_format:hasExplicitItemFormat(parsed)},warnings:[...validated.data.item_format==="json_markdown"?["settings_item_format_legacy_json_markdown_coerced_to_toon"]:[],...loadedSchemaSections.warnings]};return settingsReadCacheSignaturesEqual(signaturesBeforeSchemaLoad,signaturesAfterSchemaLoad)?setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:signaturesAfterSchemaLoad,value:cloneSettingsReadResult(result)}):clearSettingsReadCache(pmRoot),result}catch{const fallback=buildFallbackSettingsReadResult("settings_read_merge_failed");return await cacheSettingsReadResultSafe(pmRoot,trackedPathsForFailure,fallback),fallback}}const ASSIGNED_SETTINGS_PATH_SEGMENT=/^[A-Za-z0-9_-]+$/u,RESERVED_SETTINGS_PATH_SEGMENTS=new Set(["__proto__","constructor","prototype"]);function asPlainRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:void 0}function assertAssignedSettingsPaths(assignedPaths){for(const assignedPath of assignedPaths)if(assignedPath.split(".").find(segment=>!ASSIGNED_SETTINGS_PATH_SEGMENT.test(segment)||RESERVED_SETTINGS_PATH_SEGMENTS.has(segment))!==void 0)throw new PmCliError(`Settings write assignedPaths entry "${assignedPath}" is not a dotted settings path.`,EXIT_CODE.USAGE,{code:"settings_write_assigned_path_invalid",reason:"assigned_path_segment_invalid",field:assignedPath,why:"Assigned paths name settings keys; an empty, reserved or non-identifier segment cannot address one safely.",nextSteps:["Pass dotted settings keys such as context.next_ranking_policy in assignedPaths."]})}function ownRecordAt(record,segment){return asPlainRecord(Object.hasOwn(record,segment)?record[segment]:void 0)}function findAssignedSource(proposed,parents){let source=proposed;for(const segment of parents)if(source=ownRecordAt(source,segment),source===void 0)return;return source}function ensureAssignedParent(target,parents){let cursor=target;for(const segment of parents){let next=ownRecordAt(cursor,segment);next===void 0&&(next={},cursor[segment]=next),cursor=next}return cursor}function applyAssignedSettingsPaths(target,proposed,assignedPaths){for(const assignedPath of assignedPaths){const parents=assignedPath.split("."),leaf=parents.pop(),source=findAssignedSource(proposed,parents);if(source===void 0)continue;if(Object.hasOwn(source,leaf)){ensureAssignedParent(target,parents)[leaf]=structuredClone(source[leaf]);continue}if(!CORE_SETTINGS_SECTION_KEYS.includes(parents[0]??leaf))continue;const storedParent=findAssignedSource(target,parents);storedParent!==void 0&&delete storedParent[leaf]}}function applyFallbackChangeToStoredSettings(current,proposedCanonical,fallbackOrigin,assignedPaths,baseline){const baselineCanonical=baseline??JSON.parse(serializeSettings(cloneDefaults())),candidate=structuredClone(asPlainRecord(current)??{});applySettingsDelta(candidate,baselineCanonical,proposedCanonical),applyAssignedSettingsPaths(candidate,proposedCanonical,assignedPaths);const validated=validateSettings(candidate);if(!validated.success){const field=validated.path;throw new PmCliError(`Existing settings.json fails validation at ${field}; the settings write was refused and nothing was changed.`,EXIT_CODE.USAGE,{code:"settings_write_invalid_existing_schema",reason:"existing_settings_schema_invalid",field,original_code:fallbackOrigin,why:"The stored settings could not be read, so writing would either keep an invalid document or replace intended project configuration with defaults.",nextSteps:[`Fix or remove ${field} in settings.json, then retry the original command.`,"A configurable setting can also be repaired explicitly, even to its default value, with pm config <scope> set <dotted.key> <value>.","Run pm health to confirm the settings warning has cleared."]})}return`${JSON.stringify(orderObject(candidate,SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
4
4
  `}function parseExistingSettingsForWrite(raw){try{return JSON.parse(raw)}catch{throw new PmCliError("Existing settings.json is malformed; the settings write was refused.",EXIT_CODE.USAGE,{code:"settings_write_invalid_existing_json",reason:"existing_settings_json_malformed",why:"Writing defaults over malformed settings could destroy intended project configuration.",nextSteps:["Repair the syntax in .agents/pm/settings.json, then retry the original command.","Run pm health to confirm the settings warning has cleared."]})}}async function readSettings(pmRoot){return(await readSettingsWithMetadata(pmRoot)).settings}async function writeSettings(pmRoot,settings,op=SETTINGS_WRITE_OP,options={}){const assignedPaths=options.assignedPaths??[];assertAssignedSettingsPaths(assignedPaths);const settingsPath=getSettingsPath(pmRoot),source=getSettingsPersistSourceSnapshot(settings),fallbackOrigin=source?void 0:getSettingsFallbackOrigin(settings),afterRaw=serializeSettings(settings,{persist_source:source}),proposed=JSON.parse(afterRaw);try{await mutateWorkspaceJsonWithHistory({pmRoot,filePath:settingsPath,mutate:beforeRaw=>{const current=beforeRaw===null?null:parseExistingSettingsForWrite(beforeRaw);return fallbackOrigin!==void 0&&beforeRaw!==null?{raw:applyFallbackChangeToStoredSettings(current,proposed,fallbackOrigin,assignedPaths,getSettingsFallbackBaseline(settings)),result:void 0}:{raw:source?`${JSON.stringify(orderObject(reconcileSettingsSnapshot(source.persisted_settings,proposed,current),SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}