@unbrained/pm-cli 2026.5.24 → 2026.5.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/CHANGELOG.md +953 -522
  2. package/README.md +2 -10
  3. package/dist/cli/bootstrap-args.d.ts +18 -1
  4. package/dist/cli/bootstrap-args.js +143 -3
  5. package/dist/cli/bootstrap-args.js.map +1 -1
  6. package/dist/cli/commander-usage.js +134 -11
  7. package/dist/cli/commander-usage.js.map +1 -1
  8. package/dist/cli/commands/append.js +4 -3
  9. package/dist/cli/commands/append.js.map +1 -1
  10. package/dist/cli/commands/claim.js +5 -4
  11. package/dist/cli/commands/claim.js.map +1 -1
  12. package/dist/cli/commands/close.d.ts +3 -0
  13. package/dist/cli/commands/close.js +26 -3
  14. package/dist/cli/commands/close.js.map +1 -1
  15. package/dist/cli/commands/completion.d.ts +2 -2
  16. package/dist/cli/commands/completion.js +109 -56
  17. package/dist/cli/commands/completion.js.map +1 -1
  18. package/dist/cli/commands/config.d.ts +1 -1
  19. package/dist/cli/commands/config.js +82 -4
  20. package/dist/cli/commands/config.js.map +1 -1
  21. package/dist/cli/commands/create.js +7 -272
  22. package/dist/cli/commands/create.js.map +1 -1
  23. package/dist/cli/commands/delete.js +4 -3
  24. package/dist/cli/commands/delete.js.map +1 -1
  25. package/dist/cli/commands/docs.d.ts +1 -12
  26. package/dist/cli/commands/docs.js +8 -312
  27. package/dist/cli/commands/docs.js.map +1 -1
  28. package/dist/cli/commands/extension/bundled-catalog.d.ts +14 -0
  29. package/dist/cli/commands/extension/bundled-catalog.js +268 -0
  30. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -0
  31. package/dist/cli/commands/extension/doctor.d.ts +31 -0
  32. package/dist/cli/commands/extension/doctor.js +345 -0
  33. package/dist/cli/commands/extension/doctor.js.map +1 -0
  34. package/dist/cli/commands/extension/install-sources.d.ts +37 -0
  35. package/dist/cli/commands/extension/install-sources.js +384 -0
  36. package/dist/cli/commands/extension/install-sources.js.map +1 -0
  37. package/dist/cli/commands/extension/managed-state.d.ts +48 -0
  38. package/dist/cli/commands/extension/managed-state.js +172 -0
  39. package/dist/cli/commands/extension/managed-state.js.map +1 -0
  40. package/dist/cli/commands/extension/scaffold.d.ts +14 -0
  41. package/dist/cli/commands/extension/scaffold.js +202 -0
  42. package/dist/cli/commands/extension/scaffold.js.map +1 -0
  43. package/dist/cli/commands/extension/shared.d.ts +14 -0
  44. package/dist/cli/commands/extension/shared.js +106 -0
  45. package/dist/cli/commands/extension/shared.js.map +1 -0
  46. package/dist/cli/commands/extension.d.ts +36 -68
  47. package/dist/cli/commands/extension.js +143 -1422
  48. package/dist/cli/commands/extension.js.map +1 -1
  49. package/dist/cli/commands/files.d.ts +1 -12
  50. package/dist/cli/commands/files.js +11 -308
  51. package/dist/cli/commands/files.js.map +1 -1
  52. package/dist/cli/commands/get.js +4 -3
  53. package/dist/cli/commands/get.js.map +1 -1
  54. package/dist/cli/commands/health.js +17 -3
  55. package/dist/cli/commands/health.js.map +1 -1
  56. package/dist/cli/commands/history-redact.js +23 -18
  57. package/dist/cli/commands/history-redact.js.map +1 -1
  58. package/dist/cli/commands/history-repair.js +24 -18
  59. package/dist/cli/commands/history-repair.js.map +1 -1
  60. package/dist/cli/commands/legacy-none-tokens.d.ts +3 -0
  61. package/dist/cli/commands/legacy-none-tokens.js +39 -0
  62. package/dist/cli/commands/legacy-none-tokens.js.map +1 -0
  63. package/dist/cli/commands/linked-artifacts.d.ts +96 -0
  64. package/dist/cli/commands/linked-artifacts.js +335 -0
  65. package/dist/cli/commands/linked-artifacts.js.map +1 -0
  66. package/dist/cli/commands/linked-test-parsers.d.ts +28 -0
  67. package/dist/cli/commands/linked-test-parsers.js +192 -0
  68. package/dist/cli/commands/linked-test-parsers.js.map +1 -0
  69. package/dist/cli/commands/list.js +19 -5
  70. package/dist/cli/commands/list.js.map +1 -1
  71. package/dist/cli/commands/normalize.js +4 -3
  72. package/dist/cli/commands/normalize.js.map +1 -1
  73. package/dist/cli/commands/plan.d.ts +5 -0
  74. package/dist/cli/commands/plan.js +56 -8
  75. package/dist/cli/commands/plan.js.map +1 -1
  76. package/dist/cli/commands/recurrence-parsers.d.ts +26 -0
  77. package/dist/cli/commands/recurrence-parsers.js +98 -0
  78. package/dist/cli/commands/recurrence-parsers.js.map +1 -0
  79. package/dist/cli/commands/restore.js +19 -8
  80. package/dist/cli/commands/restore.js.map +1 -1
  81. package/dist/cli/commands/search.js +5 -8
  82. package/dist/cli/commands/search.js.map +1 -1
  83. package/dist/cli/commands/test/linked-command-detection.d.ts +37 -0
  84. package/dist/cli/commands/test/linked-command-detection.js +200 -0
  85. package/dist/cli/commands/test/linked-command-detection.js.map +1 -0
  86. package/dist/cli/commands/test.d.ts +1 -2
  87. package/dist/cli/commands/test.js +8 -350
  88. package/dist/cli/commands/test.js.map +1 -1
  89. package/dist/cli/commands/update-many.js +4 -3
  90. package/dist/cli/commands/update-many.js.map +1 -1
  91. package/dist/cli/commands/update.js +83 -356
  92. package/dist/cli/commands/update.js.map +1 -1
  93. package/dist/cli/commands/validate.js +32 -12
  94. package/dist/cli/commands/validate.js.map +1 -1
  95. package/dist/cli/error-guidance.d.ts +1 -0
  96. package/dist/cli/error-guidance.js +6 -2
  97. package/dist/cli/error-guidance.js.map +1 -1
  98. package/dist/cli/main.d.ts +11 -0
  99. package/dist/cli/main.js +76 -28
  100. package/dist/cli/main.js.map +1 -1
  101. package/dist/cli/register-list-query.d.ts +4 -1
  102. package/dist/cli/register-list-query.js +242 -203
  103. package/dist/cli/register-list-query.js.map +1 -1
  104. package/dist/cli/register-mutation.js +73 -11
  105. package/dist/cli/register-mutation.js.map +1 -1
  106. package/dist/cli/register-operations.js +3 -3
  107. package/dist/cli/register-operations.js.map +1 -1
  108. package/dist/cli/register-setup.js +12 -7
  109. package/dist/cli/register-setup.js.map +1 -1
  110. package/dist/cli/registration-helpers.js +3 -2
  111. package/dist/cli/registration-helpers.js.map +1 -1
  112. package/dist/cli.js +4 -3
  113. package/dist/cli.js.map +1 -1
  114. package/dist/core/config/positional-value.d.ts +44 -0
  115. package/dist/core/config/positional-value.js +109 -0
  116. package/dist/core/config/positional-value.js.map +1 -0
  117. package/dist/core/extensions/extension-capability-aliases.d.ts +14 -0
  118. package/dist/core/extensions/extension-capability-aliases.js +159 -0
  119. package/dist/core/extensions/extension-capability-aliases.js.map +1 -0
  120. package/dist/core/extensions/extension-hook-runtime.d.ts +13 -0
  121. package/dist/core/extensions/extension-hook-runtime.js +414 -0
  122. package/dist/core/extensions/extension-hook-runtime.js.map +1 -0
  123. package/dist/core/extensions/extension-policy.d.ts +69 -0
  124. package/dist/core/extensions/extension-policy.js +481 -0
  125. package/dist/core/extensions/extension-policy.js.map +1 -0
  126. package/dist/core/extensions/extension-registries.d.ts +8 -0
  127. package/dist/core/extensions/extension-registries.js +52 -0
  128. package/dist/core/extensions/extension-registries.js.map +1 -0
  129. package/dist/core/extensions/extension-runtime-helpers.d.ts +6 -0
  130. package/dist/core/extensions/extension-runtime-helpers.js +29 -0
  131. package/dist/core/extensions/extension-runtime-helpers.js.map +1 -0
  132. package/dist/core/extensions/extension-types.d.ts +13 -39
  133. package/dist/core/extensions/extension-types.js +34 -2
  134. package/dist/core/extensions/extension-types.js.map +1 -1
  135. package/dist/core/extensions/index.d.ts +7 -0
  136. package/dist/core/extensions/index.js +11 -2
  137. package/dist/core/extensions/index.js.map +1 -1
  138. package/dist/core/extensions/loader.d.ts +4 -22
  139. package/dist/core/extensions/loader.js +22 -1139
  140. package/dist/core/extensions/loader.js.map +1 -1
  141. package/dist/core/history/drift-scan.d.ts +11 -0
  142. package/dist/core/history/drift-scan.js +114 -32
  143. package/dist/core/history/drift-scan.js.map +1 -1
  144. package/dist/core/history/history-rewrite.d.ts +43 -0
  145. package/dist/core/history/history-rewrite.js +48 -0
  146. package/dist/core/history/history-rewrite.js.map +1 -0
  147. package/dist/core/history/history.js +5 -4
  148. package/dist/core/history/history.js.map +1 -1
  149. package/dist/core/history/replay.js +4 -3
  150. package/dist/core/history/replay.js.map +1 -1
  151. package/dist/core/item/item-record.d.ts +19 -0
  152. package/dist/core/item/item-record.js +24 -0
  153. package/dist/core/item/item-record.js.map +1 -0
  154. package/dist/core/output/mutation-projection.d.ts +31 -0
  155. package/dist/core/output/mutation-projection.js +103 -0
  156. package/dist/core/output/mutation-projection.js.map +1 -0
  157. package/dist/core/output/output.d.ts +2 -0
  158. package/dist/core/output/output.js +5 -3
  159. package/dist/core/output/output.js.map +1 -1
  160. package/dist/core/schema/runtime-schema.js +8 -38
  161. package/dist/core/schema/runtime-schema.js.map +1 -1
  162. package/dist/core/search/vector-stores.js +46 -9
  163. package/dist/core/search/vector-stores.js.map +1 -1
  164. package/dist/core/sentry/helpers.d.ts +1 -1
  165. package/dist/core/sentry/helpers.js +20 -3
  166. package/dist/core/sentry/helpers.js.map +1 -1
  167. package/dist/core/shared/command-types.d.ts +1 -0
  168. package/dist/core/shared/command-types.js +2 -2
  169. package/dist/core/shared/command-types.js.map +1 -1
  170. package/dist/core/shared/constants.d.ts +10 -1
  171. package/dist/core/shared/constants.js +56 -58
  172. package/dist/core/shared/constants.js.map +1 -1
  173. package/dist/core/shared/levenshtein.js +23 -7
  174. package/dist/core/shared/levenshtein.js.map +1 -1
  175. package/dist/core/shared/primitives.d.ts +23 -0
  176. package/dist/core/shared/primitives.js +39 -2
  177. package/dist/core/shared/primitives.js.map +1 -1
  178. package/dist/core/store/front-matter-cache.d.ts +16 -2
  179. package/dist/core/store/front-matter-cache.js +99 -33
  180. package/dist/core/store/front-matter-cache.js.map +1 -1
  181. package/dist/core/store/item-store.js +8 -73
  182. package/dist/core/store/item-store.js.map +1 -1
  183. package/dist/mcp/server.js +76 -28
  184. package/dist/mcp/server.js.map +1 -1
  185. package/dist/sdk/cli-contracts/enum-contracts.d.ts +20 -0
  186. package/dist/sdk/cli-contracts/enum-contracts.js +156 -0
  187. package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -0
  188. package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +14 -0
  189. package/dist/sdk/cli-contracts/tool-option-contracts.js +243 -0
  190. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -0
  191. package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +11 -0
  192. package/dist/sdk/cli-contracts/tool-parameter-tables.js +901 -0
  193. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -0
  194. package/dist/sdk/cli-contracts.d.ts +11 -33
  195. package/dist/sdk/cli-contracts.js +30 -1356
  196. package/dist/sdk/cli-contracts.js.map +1 -1
  197. package/dist/sdk/package-import-adapters.d.ts +74 -0
  198. package/dist/sdk/package-import-adapters.js +186 -0
  199. package/dist/sdk/package-import-adapters.js.map +1 -0
  200. package/dist/sdk/package-runtime-options.d.ts +26 -0
  201. package/dist/sdk/package-runtime-options.js +71 -0
  202. package/dist/sdk/package-runtime-options.js.map +1 -0
  203. package/dist/sdk/runtime.d.ts +2 -0
  204. package/dist/sdk/runtime.js +4 -2
  205. package/dist/sdk/runtime.js.map +1 -1
  206. package/docs/AGENT_GUIDE.md +6 -10
  207. package/docs/CLAUDE_CODE_PLUGIN.md +5 -28
  208. package/docs/CODEX_PLUGIN.md +5 -5
  209. package/docs/COMMANDS.md +19 -3
  210. package/docs/CONFIGURATION.md +15 -0
  211. package/docs/EXTENSIONS.md +4 -63
  212. package/docs/RELEASING.md +4 -4
  213. package/marketplace.json +7 -3
  214. package/package.json +9 -6
  215. package/packages/pm-beads/extensions/beads/index.js +2 -49
  216. package/packages/pm-beads/extensions/beads/index.ts +2 -54
  217. package/packages/pm-beads/extensions/beads/runtime-loader.js +86 -0
  218. package/packages/pm-beads/extensions/beads/runtime-loader.ts +88 -0
  219. package/packages/pm-beads/extensions/beads/runtime.js +26 -115
  220. package/packages/pm-beads/extensions/beads/runtime.ts +33 -132
  221. package/packages/pm-calendar/extensions/calendar/index.js +47 -2
  222. package/packages/pm-calendar/extensions/calendar/index.ts +52 -2
  223. package/packages/pm-calendar/extensions/calendar/runtime.js +1 -0
  224. package/packages/pm-calendar/extensions/calendar/runtime.ts +1 -0
  225. package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +14 -41
  226. package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +25 -41
  227. package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +10 -50
  228. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +17 -50
  229. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +8 -40
  230. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +10 -40
  231. package/packages/pm-search-advanced/extensions/search-advanced/index.js +1 -1
  232. package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +4 -37
  233. package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +6 -37
  234. package/packages/pm-todos/extensions/todos/index.js +3 -50
  235. package/packages/pm-todos/extensions/todos/index.ts +3 -55
  236. package/packages/pm-todos/extensions/todos/runtime-loader.js +86 -0
  237. package/packages/pm-todos/extensions/todos/runtime-loader.ts +88 -0
  238. package/packages/pm-todos/extensions/todos/runtime.js +24 -117
  239. package/packages/pm-todos/extensions/todos/runtime.ts +32 -129
  240. package/plugins/pm-claude/README.md +2 -2
  241. package/plugins/pm-claude/commands/pm-planner.md +1 -15
  242. package/plugins/pm-claude/scripts/pm-mcp-server.mjs +5 -2
  243. package/plugins/pm-claude/skills/pm-planner/SKILL.md +3 -21
  244. package/plugins/pm-codex/scripts/pm-mcp-server.mjs +15 -6
  245. package/plugins/pm-codex/skills/pm-native/SKILL.md +1 -13
  246. package/PRD.md +0 -1734
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recurrence-parsers.js","sources":["cli/commands/recurrence-parsers.ts"],"sourceRoot":"/","sourcesContent":["import { parseOptionalNumber } from \"../../core/item/parse.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { resolveIsoOrRelative } from \"../../core/shared/time.js\";\nimport {\n RECURRENCE_FREQUENCY_VALUES,\n RECURRENCE_WEEKDAY_VALUES,\n weekdayOrderIndex,\n} from \"../../types/index.js\";\nimport type { RecurrenceRule } from \"../../types/index.js\";\n\n/**\n * Shared calendar recurrence/event parsing helpers used by the `create` and\n * `update` commands. Extracted verbatim from create.ts and update.ts (pm-why9).\n *\n * `parseEventBoolean`, `parseDelimitedList`, and `ensureEnumValue` were\n * byte-identical between the two commands (update spelled `ensureEnumValue` as\n * `ensureEnum`).\n *\n * `parseRecurrenceRule` was identical apart from the recur_interval/recur_count\n * \"provided\" guard: create used `intervalRaw !== undefined` (an empty\n * `recur_interval=` is parsed and rejected), while update used the truthy\n * `intervalRaw ?` (an empty value is skipped). That distinction is preserved\n * via the `emptyNumericGuard` option so both call sites keep their exact\n * behaviour, including error strings.\n */\n\nexport function parseEventBoolean(value: string, flag: string): boolean {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"true\" || normalized === \"1\" || normalized === \"yes\") {\n return true;\n }\n if (normalized === \"false\" || normalized === \"0\" || normalized === \"no\") {\n return false;\n }\n throw new PmCliError(`${flag} must be one of true|false|1|0|yes|no`, EXIT_CODE.USAGE);\n}\n\nexport function parseDelimitedList(raw: string | undefined): string[] {\n if (!raw) {\n return [];\n }\n return raw\n .split(\"|\")\n .map((value) => value.trim())\n .filter((value) => value.length > 0);\n}\n\nexport function ensureEnumValue<T extends string>(value: string, allowed: readonly T[], label: string): T {\n if (!allowed.includes(value as T)) {\n throw new PmCliError(`Invalid ${label} value \"${value}\". Allowed: ${allowed.join(\", \")}`, EXIT_CODE.USAGE);\n }\n return value as T;\n}\n\n/**\n * `\"defined\"` parses `recur_interval=`/`recur_count=` (empty values), matching\n * the historical `create` behaviour. `\"truthy\"` skips empty values, matching\n * the historical `update` behaviour.\n */\nexport type RecurrenceEmptyNumericGuard = \"defined\" | \"truthy\";\n\nexport function parseRecurrenceRule(\n kv: Record<string, string>,\n startAt: string,\n nowValue: Date,\n emptyNumericGuard: RecurrenceEmptyNumericGuard,\n): RecurrenceRule | undefined {\n const freqRaw = kv.recur_freq?.trim();\n const intervalRaw = kv.recur_interval?.trim();\n const countRaw = kv.recur_count?.trim();\n const untilRaw = kv.recur_until?.trim();\n const byWeekdayRaw = kv.recur_by_weekday?.trim();\n const byMonthDayRaw = kv.recur_by_month_day?.trim();\n const exdatesRaw = kv.recur_exdates?.trim();\n\n const recurrenceInputsProvided = [freqRaw, intervalRaw, countRaw, untilRaw, byWeekdayRaw, byMonthDayRaw, exdatesRaw].some(\n (value) => value !== undefined,\n );\n if (!recurrenceInputsProvided) {\n return undefined;\n }\n if (!freqRaw) {\n throw new PmCliError(\"--event recurrence fields require recur_freq=<daily|weekly|monthly|yearly>\", EXIT_CODE.USAGE);\n }\n\n const numericProvided = (raw: string | undefined): boolean =>\n emptyNumericGuard === \"defined\" ? raw !== undefined : Boolean(raw);\n\n const freq = ensureEnumValue(freqRaw.toLowerCase(), RECURRENCE_FREQUENCY_VALUES, \"event recurrence frequency\");\n const interval = numericProvided(intervalRaw) ? parseOptionalNumber(intervalRaw as string, \"event recur_interval\") : undefined;\n if (interval !== undefined && (!Number.isInteger(interval) || interval < 1)) {\n throw new PmCliError(\"--event recur_interval must be an integer >= 1\", EXIT_CODE.USAGE);\n }\n const count = numericProvided(countRaw) ? parseOptionalNumber(countRaw as string, \"event recur_count\") : undefined;\n if (count !== undefined && (!Number.isInteger(count) || count < 1)) {\n throw new PmCliError(\"--event recur_count must be an integer >= 1\", EXIT_CODE.USAGE);\n }\n const until = untilRaw ? resolveIsoOrRelative(untilRaw, nowValue, \"event.recur_until\") : undefined;\n if (until && until < startAt) {\n throw new PmCliError(\"--event recur_until must be at or after start\", EXIT_CODE.USAGE);\n }\n\n const byWeekday = Array.from(\n new Set(\n parseDelimitedList(byWeekdayRaw).map((value) => ensureEnumValue(value.toLowerCase(), RECURRENCE_WEEKDAY_VALUES, \"event weekday\")),\n ),\n ).sort(\n (left, right) =>\n weekdayOrderIndex(left as (typeof RECURRENCE_WEEKDAY_VALUES)[number]) -\n weekdayOrderIndex(right as (typeof RECURRENCE_WEEKDAY_VALUES)[number]),\n );\n\n const byMonthDay = Array.from(\n new Set(\n parseDelimitedList(byMonthDayRaw).map((value) => {\n const day = parseOptionalNumber(value, \"event recur_by_month_day\");\n if (!Number.isInteger(day) || day < 1 || day > 31) {\n throw new PmCliError(\"--event recur_by_month_day values must be integers 1..31\", EXIT_CODE.USAGE);\n }\n return day;\n }),\n ),\n ).sort((left, right) => left - right);\n\n const exdates = Array.from(\n new Set(parseDelimitedList(exdatesRaw).map((value) => resolveIsoOrRelative(value, nowValue, \"event.recur_exdates\"))),\n ).sort((left, right) => left.localeCompare(right));\n\n return {\n freq,\n interval,\n count,\n until,\n by_weekday: byWeekday.length > 0 ? byWeekday : undefined,\n by_month_day: byMonthDay.length > 0 ? byMonthDay : undefined,\n exdates: exdates.length > 0 ? exdates : undefined,\n };\n}\n"],"names":[],"mappings":"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","debugId":"b55435a8-c253-5997-8afb-cbf2e197b649"}
@@ -1,8 +1,8 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="252a32c4-fa45-56b2-8eb3-2b421d885b9a")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d40fa5ec-9a3f-52de-980b-b83b2e0021d1")}catch(e){}}();
3
3
  import jsonPatch from "fast-json-patch";
4
4
  import fs from "node:fs/promises";
5
- import { pathExists, writeFileAtomic } from "../../core/fs/fs-utils.js";
5
+ import { pathExists, readFileIfExists, writeFileAtomic } from "../../core/fs/fs-utils.js";
6
6
  import { appendHistoryEntry, createHistoryEntry } from "../../core/history/history.js";
7
7
  import { EMPTY_REPLAY_DOCUMENT, normalizeReplayPatchOps, replayHash, toReplayDocument, } from "../../core/history/replay.js";
8
8
  import { enforceHistoryStreamPolicyForItem } from "../../core/history/history-stream-policy.js";
@@ -219,6 +219,7 @@ export async function runRestore(id, target, options, global) {
219
219
  const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
220
220
  const subject = await resolveRestoreSubject(pmRoot, id, settings, typeRegistry.type_to_folder);
221
221
  const resolvedId = subject.id;
222
+ const historyRawBeforeLock = await readFileIfExists(subject.historyPath);
222
223
  const history = await readHistoryEntries(subject.historyPath, resolvedId);
223
224
  if (history.length === 0) {
224
225
  throw new PmCliError(`No history exists for ${resolvedId}; restore is unavailable.`, EXIT_CODE.NOT_FOUND);
@@ -232,17 +233,27 @@ export async function runRestore(id, target, options, global) {
232
233
  if (restoredDocument.metadata.id !== resolvedId) {
233
234
  throw new PmCliError(`Restore target resolved to item ${restoredDocument.metadata.id}, expected ${resolvedId}.`, EXIT_CODE.GENERIC_FAILURE);
234
235
  }
236
+ const loadedItemBeforeLock = subject.located ? await readLocatedItem(subject.located, { schema: settings.schema }) : null;
237
+ const currentItemRawBeforeLock = loadedItemBeforeLock?.raw ?? null;
235
238
  const author = resolveAuthor(options.author, settings.author_default);
236
239
  const releaseLock = await acquireLock(pmRoot, resolvedId, settings.locks.ttl_seconds, author, Boolean(options.force), settings.governance.force_required_for_stale_lock);
237
240
  try {
238
- const existingItemPath = subject.located?.itemPath ?? null;
241
+ const historyRawUnderLock = await readFileIfExists(subject.historyPath);
242
+ if (historyRawUnderLock !== historyRawBeforeLock) {
243
+ throw new PmCliError(`History for ${resolvedId} changed while waiting for lock; retry restore.`, EXIT_CODE.CONFLICT);
244
+ }
245
+ const locatedUnderLock = await locateItem(pmRoot, resolvedId, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
246
+ const loadedItemUnderLock = locatedUnderLock ? await readLocatedItem(locatedUnderLock, { schema: settings.schema }) : null;
247
+ if ((loadedItemUnderLock?.raw ?? null) !== currentItemRawBeforeLock) {
248
+ throw new PmCliError(`Item ${resolvedId} changed while waiting for lock; retry restore.`, EXIT_CODE.CONFLICT);
249
+ }
250
+ const existingItemPath = locatedUnderLock?.itemPath ?? null;
239
251
  const itemFormat = "toon";
240
252
  let resolvedCurrentDocument;
241
253
  let resolvedOriginalRaw = null;
242
- if (subject.located) {
243
- const loaded = await readLocatedItem(subject.located, { schema: settings.schema });
244
- resolvedCurrentDocument = loaded.document;
245
- resolvedOriginalRaw = loaded.raw;
254
+ if (loadedItemUnderLock) {
255
+ resolvedCurrentDocument = loadedItemUnderLock.document;
256
+ resolvedOriginalRaw = loadedItemUnderLock.raw;
246
257
  }
247
258
  else {
248
259
  resolvedCurrentDocument = replayCurrentDocument(history);
@@ -319,4 +330,4 @@ export async function runRestore(id, target, options, global) {
319
330
  }
320
331
  }
321
332
  //# sourceMappingURL=restore.js.map
322
- //# debugId=252a32c4-fa45-56b2-8eb3-2b421d885b9a
333
+ //# debugId=d40fa5ec-9a3f-52de-980b-b83b2e0021d1
@@ -1 +1 @@
1
- {"version":3,"file":"restore.js","sources":["cli/commands/restore.ts"],"sourceRoot":"/","sourcesContent":["import jsonPatch from \"fast-json-patch\";\nimport fs from \"node:fs/promises\";\nimport { pathExists, writeFileAtomic } from \"../../core/fs/fs-utils.js\";\nimport { appendHistoryEntry, createHistoryEntry } from \"../../core/history/history.js\";\nimport {\n EMPTY_REPLAY_DOCUMENT,\n normalizeReplayPatchOps,\n replayHash,\n toReplayDocument,\n type ReplayDocument as CanonicalReplayDocument,\n} from \"../../core/history/replay.js\";\nimport { enforceHistoryStreamPolicyForItem } from \"../../core/history/history-stream-policy.js\";\nimport { normalizeItemId, normalizeRawItemId } from \"../../core/item/id.js\";\nimport { canonicalDocument, serializeItemDocument } from \"../../core/item/item-format.js\";\nimport { resolveItemTypeRegistry } from \"../../core/item/type-registry.js\";\nimport { acquireLock } from \"../../core/lock/lock.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { getActiveExtensionRegistrations, runActiveOnWriteHooks } from \"../../core/extensions/index.js\";\nimport { locateItem, readLocatedItem } from \"../../core/store/item-store.js\";\nimport { getHistoryPath, getItemPath, getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { resolveAuthor } from \"../../core/shared/author.js\";\nimport type { HistoryEntry, HistoryPatchOp, ItemDocument, ItemMetadata } from \"../../types/index.js\";\nimport { readHistoryEntries } from \"./history.js\";\n\ninterface ResolvedRestoreTarget {\n kind: \"version\" | \"timestamp\";\n raw: string;\n historyIndex: number;\n}\n\ninterface ResolvedRestoreSubject {\n id: string;\n historyPath: string;\n located: Awaited<ReturnType<typeof locateItem>>;\n historyPolicyWarnings: string[];\n}\n\nexport interface RestoreCommandOptions {\n author?: string;\n message?: string;\n force?: boolean;\n}\n\nexport interface RestoreResult {\n item: ItemMetadata;\n restored_from: {\n kind: \"version\" | \"timestamp\";\n target: string;\n history_index: number;\n entry_ts: string;\n entry_op: string;\n };\n changed_fields: string[];\n warnings: string[];\n}\n\nfunction ensureReplayTarget(target: string, history: HistoryEntry[]): ResolvedRestoreTarget {\n const trimmed = target.trim();\n if (!trimmed) {\n throw new PmCliError(\"Missing restore target. Use a timestamp or version number.\", EXIT_CODE.USAGE);\n }\n\n if (/^\\d+$/.test(trimmed)) {\n const version = Number(trimmed);\n if (!Number.isSafeInteger(version) || version < 1 || version > history.length) {\n throw new PmCliError(\n `Restore version must be between 1 and ${history.length} for this item.`,\n EXIT_CODE.USAGE,\n );\n }\n return {\n kind: \"version\",\n raw: trimmed,\n historyIndex: version - 1,\n };\n }\n\n const parsedTarget = Date.parse(trimmed);\n if (!Number.isFinite(parsedTarget)) {\n throw new PmCliError(\n `Invalid restore target \"${target}\". Use a positive version number or ISO timestamp.`,\n EXIT_CODE.USAGE,\n );\n }\n\n let index = -1;\n for (let i = 0; i < history.length; i += 1) {\n const entryTimestamp = Date.parse(history[i].ts);\n if (!Number.isFinite(entryTimestamp)) {\n throw new PmCliError(\n `History for this item contains invalid timestamp at entry ${i + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n if (entryTimestamp <= parsedTarget) {\n index = i;\n }\n }\n\n if (index < 0) {\n throw new PmCliError(`No history entries exist at or before timestamp ${trimmed}.`, EXIT_CODE.USAGE);\n }\n\n return {\n kind: \"timestamp\",\n raw: trimmed,\n historyIndex: index,\n };\n}\n\nfunction extractPatchFailureContext(\n patch: HistoryPatchOp[],\n error: unknown,\n): { patchIndex?: number; op?: string; path?: string; from?: string; reason?: string } {\n const context: { patchIndex?: number; op?: string; path?: string; from?: string; reason?: string } = {};\n if (error instanceof Error && error.message.trim().length > 0) {\n context.reason = error.message.trim();\n }\n if (typeof error !== \"object\" || error === null) {\n return context;\n }\n const candidate = error as {\n index?: unknown;\n operation?: unknown;\n };\n if (typeof candidate.index === \"number\" && Number.isInteger(candidate.index) && candidate.index >= 0) {\n context.patchIndex = candidate.index;\n }\n const operationRecord =\n typeof candidate.operation === \"object\" && candidate.operation !== null\n ? (candidate.operation as { op?: unknown; path?: unknown; from?: unknown })\n : null;\n if (operationRecord && typeof operationRecord.op === \"string\") {\n context.op = operationRecord.op;\n }\n if (operationRecord && typeof operationRecord.path === \"string\") {\n context.path = operationRecord.path;\n }\n if (operationRecord && typeof operationRecord.from === \"string\") {\n context.from = operationRecord.from;\n }\n if ((context.op === undefined || context.path === undefined) && context.patchIndex !== undefined) {\n const fallback = patch[context.patchIndex];\n if (fallback) {\n context.op = context.op ?? fallback.op;\n context.path = context.path ?? fallback.path;\n context.from = context.from ?? fallback.from;\n }\n }\n return context;\n}\n\nfunction applyHistoryPatch(\n current: CanonicalReplayDocument,\n patch: HistoryPatchOp[],\n entryNumber: number,\n entryOp: string,\n): CanonicalReplayDocument {\n try {\n const normalizedPatch = normalizeReplayPatchOps(patch);\n const applied = jsonPatch.applyPatch(\n structuredClone(current),\n normalizedPatch as jsonPatch.Operation[],\n true,\n false,\n ).newDocument as unknown;\n if (\n typeof applied !== \"object\" ||\n applied === null ||\n !(\"metadata\" in applied) ||\n !(\"body\" in applied) ||\n typeof (applied as { body: unknown }).body !== \"string\" ||\n typeof (applied as { metadata: unknown }).metadata !== \"object\" ||\n (applied as { metadata: unknown }).metadata === null\n ) {\n throw new PmCliError(\n `History replay produced an invalid document shape at entry ${entryNumber}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n const replay = applied as { metadata: Record<string, unknown>; body: string };\n return {\n metadata: replay.metadata,\n body: replay.body,\n };\n } catch (error: unknown) {\n if (error instanceof PmCliError) {\n throw error;\n }\n const failureContext = extractPatchFailureContext(patch, error);\n const contextTokens = [\n `history_op=${entryOp}`,\n failureContext.patchIndex !== undefined ? `patch_index=${failureContext.patchIndex}` : null,\n failureContext.op ? `op=${failureContext.op}` : null,\n failureContext.path ? `path=${failureContext.path}` : null,\n failureContext.from ? `from=${failureContext.from}` : null,\n ].filter((token): token is string => token !== null);\n const reasonSuffix = failureContext.reason ? ` ${failureContext.reason}` : \"\";\n throw new PmCliError(\n `Failed to apply history patch at entry ${entryNumber} (${contextTokens.join(\", \")}).${reasonSuffix}`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n}\n\nfunction replayToTarget(history: HistoryEntry[], targetIndex: number): CanonicalReplayDocument {\n let document: CanonicalReplayDocument = structuredClone(EMPTY_REPLAY_DOCUMENT);\n\n for (let i = 0; i <= targetIndex; i += 1) {\n const entry = history[i];\n const beforeHash = replayHash(document);\n if (beforeHash !== entry.before_hash) {\n throw new PmCliError(\n `History hash mismatch before replay at entry ${i + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n\n document = applyHistoryPatch(document, entry.patch, i + 1, entry.op);\n\n const afterHash = replayHash(document);\n if (afterHash !== entry.after_hash) {\n throw new PmCliError(\n `History hash mismatch after replay at entry ${i + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n }\n\n return document;\n}\n\nfunction ensureMaterializedRestoreTarget(\n replayDocument: CanonicalReplayDocument,\n target: ResolvedRestoreTarget,\n): CanonicalReplayDocument {\n if (Object.keys(replayDocument.metadata).length > 0) {\n return replayDocument;\n }\n throw new PmCliError(\n `Restore target ${target.raw} resolves to a deleted state; choose a version or timestamp where the item exists.`,\n EXIT_CODE.USAGE,\n );\n}\n\nfunction replayCurrentDocument(history: HistoryEntry[]): ItemDocument {\n const currentReplay = replayToTarget(history, history.length - 1);\n if (Object.keys(currentReplay.metadata).length === 0) {\n return {\n metadata: {} as ItemMetadata,\n body: currentReplay.body,\n };\n }\n return canonicalDocument({\n metadata: currentReplay.metadata as unknown as ItemMetadata,\n body: currentReplay.body,\n });\n}\n\nasync function resolveRestoreSubject(\n pmRoot: string,\n id: string,\n settings: Awaited<ReturnType<typeof readSettings>>,\n typeToFolder: Record<string, string>,\n): Promise<ResolvedRestoreSubject> {\n const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeToFolder);\n if (located) {\n const historyPath = getHistoryPath(pmRoot, located.id);\n const historyPolicy = await enforceHistoryStreamPolicyForItem({\n pmRoot,\n settings,\n itemId: located.id,\n commandLabel: \"restore\",\n });\n return {\n id: located.id,\n historyPath,\n located,\n historyPolicyWarnings: historyPolicy.warnings,\n };\n }\n\n const normalizedId = normalizeItemId(id, settings.id_prefix);\n const rawNormalizedId = normalizeRawItemId(id);\n const candidateIds = normalizedId === rawNormalizedId ? [normalizedId] : [normalizedId, rawNormalizedId];\n for (const candidateId of candidateIds) {\n const historyPath = getHistoryPath(pmRoot, candidateId);\n if (await pathExists(historyPath)) {\n return {\n id: candidateId,\n historyPath,\n located: null,\n historyPolicyWarnings: [],\n };\n }\n }\n\n throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);\n}\n\nfunction changedFields(beforeDocument: ItemDocument, afterDocument: ItemDocument): string[] {\n const beforeReplay = toReplayDocument(beforeDocument);\n const afterReplay = toReplayDocument(afterDocument);\n const patch = jsonPatch.compare(beforeReplay, afterReplay) as HistoryPatchOp[];\n const fields = new Set<string>();\n\n for (const op of patch) {\n if (op.path === \"/body\" || op.path.startsWith(\"/body/\")) {\n fields.add(\"body\");\n continue;\n }\n const segment = op.path.replace(/^\\/(?:metadata|front_matter)\\/?/, \"\").split(\"/\")[0];\n fields.add(segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n }\n\n return Array.from(fields).sort((a, b) => a.localeCompare(b));\n}\n\nexport async function runRestore(\n id: string,\n target: string,\n options: RestoreCommandOptions,\n global: GlobalOptions,\n): Promise<RestoreResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);\n }\n\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());\n const subject = await resolveRestoreSubject(pmRoot, id, settings, typeRegistry.type_to_folder);\n const resolvedId = subject.id;\n const history = await readHistoryEntries(subject.historyPath, resolvedId);\n if (history.length === 0) {\n throw new PmCliError(`No history exists for ${resolvedId}; restore is unavailable.`, EXIT_CODE.NOT_FOUND);\n }\n\n const resolvedTarget = ensureReplayTarget(target, history);\n const replayDocument = ensureMaterializedRestoreTarget(replayToTarget(history, resolvedTarget.historyIndex), resolvedTarget);\n const restoredDocument = canonicalDocument(\n {\n metadata: replayDocument.metadata as unknown as ItemMetadata,\n body: replayDocument.body,\n },\n { schema: settings.schema },\n );\n\n if (restoredDocument.metadata.id !== resolvedId) {\n throw new PmCliError(\n `Restore target resolved to item ${restoredDocument.metadata.id}, expected ${resolvedId}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n\n const author = resolveAuthor(options.author, settings.author_default);\n const releaseLock = await acquireLock(\n pmRoot,\n resolvedId,\n settings.locks.ttl_seconds,\n author,\n Boolean(options.force),\n settings.governance.force_required_for_stale_lock,\n );\n\n try {\n const existingItemPath = subject.located?.itemPath ?? null;\n const itemFormat = \"toon\";\n let resolvedCurrentDocument: ItemDocument;\n let resolvedOriginalRaw: string | null = null;\n if (subject.located) {\n const loaded = await readLocatedItem(subject.located, { schema: settings.schema });\n resolvedCurrentDocument = loaded.document;\n resolvedOriginalRaw = loaded.raw;\n } else {\n resolvedCurrentDocument = replayCurrentDocument(history);\n }\n const assigned = resolvedCurrentDocument.metadata.assignee?.trim();\n const ownershipWarnings: string[] = [];\n const hasOwnershipConflict = assigned && assigned !== author && !options.force;\n if (hasOwnershipConflict) {\n if (settings.governance.ownership_enforcement === \"strict\") {\n throw new PmCliError(\n `Item ${resolvedId} is assigned to ${assigned}. Use --force to override.`,\n EXIT_CODE.CONFLICT,\n );\n }\n if (settings.governance.ownership_enforcement === \"warn\") {\n ownershipWarnings.push(`ownership_warning:assignee_conflict:${resolvedId}:${assigned}`);\n }\n }\n\n const serializedRestore = serializeItemDocument(restoredDocument, { format: itemFormat, schema: settings.schema });\n const restoredItemPath = getItemPath(\n pmRoot,\n restoredDocument.metadata.type,\n resolvedId,\n itemFormat,\n typeRegistry.type_to_folder,\n );\n await writeFileAtomic(restoredItemPath, serializedRestore);\n if (existingItemPath && restoredItemPath !== existingItemPath) {\n await fs.rm(existingItemPath);\n }\n\n const historyEntry = createHistoryEntry({\n nowIso: nowIso(),\n author,\n op: \"restore\",\n before: resolvedCurrentDocument,\n after: restoredDocument,\n message: options.message,\n });\n\n try {\n await appendHistoryEntry(subject.historyPath, historyEntry);\n } catch (error: unknown) {\n if (existingItemPath && resolvedOriginalRaw !== null && restoredItemPath !== existingItemPath) {\n await writeFileAtomic(existingItemPath, resolvedOriginalRaw);\n await fs.rm(restoredItemPath, { force: true });\n } else if (existingItemPath && resolvedOriginalRaw !== null) {\n await writeFileAtomic(existingItemPath, resolvedOriginalRaw);\n } else {\n await fs.rm(restoredItemPath, { force: true });\n }\n throw error;\n }\n const hookWarnings = [\n ...(await runActiveOnWriteHooks({\n path: restoredItemPath,\n scope: \"project\",\n op: \"restore\",\n })),\n ...(await runActiveOnWriteHooks({\n path: subject.historyPath,\n scope: \"project\",\n op: \"restore:history\",\n })),\n ];\n\n const targetEntry = history[resolvedTarget.historyIndex];\n return {\n item: restoredDocument.metadata,\n restored_from: {\n kind: resolvedTarget.kind,\n target: resolvedTarget.raw,\n history_index: resolvedTarget.historyIndex + 1,\n entry_ts: targetEntry.ts,\n entry_op: targetEntry.op,\n },\n changed_fields: changedFields(resolvedCurrentDocument, restoredDocument),\n warnings: [...subject.historyPolicyWarnings, ...ownershipWarnings, ...hookWarnings],\n };\n } finally {\n await releaseLock();\n }\n}\n"],"names":[],"mappings":"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","debugId":"252a32c4-fa45-56b2-8eb3-2b421d885b9a"}
1
+ {"version":3,"file":"restore.js","sources":["cli/commands/restore.ts"],"sourceRoot":"/","sourcesContent":["import jsonPatch from \"fast-json-patch\";\nimport fs from \"node:fs/promises\";\nimport { pathExists, readFileIfExists, writeFileAtomic } from \"../../core/fs/fs-utils.js\";\nimport { appendHistoryEntry, createHistoryEntry } from \"../../core/history/history.js\";\nimport {\n EMPTY_REPLAY_DOCUMENT,\n normalizeReplayPatchOps,\n replayHash,\n toReplayDocument,\n type ReplayDocument as CanonicalReplayDocument,\n} from \"../../core/history/replay.js\";\nimport { enforceHistoryStreamPolicyForItem } from \"../../core/history/history-stream-policy.js\";\nimport { normalizeItemId, normalizeRawItemId } from \"../../core/item/id.js\";\nimport { canonicalDocument, serializeItemDocument } from \"../../core/item/item-format.js\";\nimport { resolveItemTypeRegistry } from \"../../core/item/type-registry.js\";\nimport { acquireLock } from \"../../core/lock/lock.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { getActiveExtensionRegistrations, runActiveOnWriteHooks } from \"../../core/extensions/index.js\";\nimport { locateItem, readLocatedItem } from \"../../core/store/item-store.js\";\nimport { getHistoryPath, getItemPath, getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport { resolveAuthor } from \"../../core/shared/author.js\";\nimport type { HistoryEntry, HistoryPatchOp, ItemDocument, ItemMetadata } from \"../../types/index.js\";\nimport { readHistoryEntries } from \"./history.js\";\n\ninterface ResolvedRestoreTarget {\n kind: \"version\" | \"timestamp\";\n raw: string;\n historyIndex: number;\n}\n\ninterface ResolvedRestoreSubject {\n id: string;\n historyPath: string;\n located: Awaited<ReturnType<typeof locateItem>>;\n historyPolicyWarnings: string[];\n}\n\nexport interface RestoreCommandOptions {\n author?: string;\n message?: string;\n force?: boolean;\n}\n\nexport interface RestoreResult {\n item: ItemMetadata;\n restored_from: {\n kind: \"version\" | \"timestamp\";\n target: string;\n history_index: number;\n entry_ts: string;\n entry_op: string;\n };\n changed_fields: string[];\n warnings: string[];\n}\n\nfunction ensureReplayTarget(target: string, history: HistoryEntry[]): ResolvedRestoreTarget {\n const trimmed = target.trim();\n if (!trimmed) {\n throw new PmCliError(\"Missing restore target. Use a timestamp or version number.\", EXIT_CODE.USAGE);\n }\n\n if (/^\\d+$/.test(trimmed)) {\n const version = Number(trimmed);\n if (!Number.isSafeInteger(version) || version < 1 || version > history.length) {\n throw new PmCliError(\n `Restore version must be between 1 and ${history.length} for this item.`,\n EXIT_CODE.USAGE,\n );\n }\n return {\n kind: \"version\",\n raw: trimmed,\n historyIndex: version - 1,\n };\n }\n\n const parsedTarget = Date.parse(trimmed);\n if (!Number.isFinite(parsedTarget)) {\n throw new PmCliError(\n `Invalid restore target \"${target}\". Use a positive version number or ISO timestamp.`,\n EXIT_CODE.USAGE,\n );\n }\n\n let index = -1;\n for (let i = 0; i < history.length; i += 1) {\n const entryTimestamp = Date.parse(history[i].ts);\n if (!Number.isFinite(entryTimestamp)) {\n throw new PmCliError(\n `History for this item contains invalid timestamp at entry ${i + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n if (entryTimestamp <= parsedTarget) {\n index = i;\n }\n }\n\n if (index < 0) {\n throw new PmCliError(`No history entries exist at or before timestamp ${trimmed}.`, EXIT_CODE.USAGE);\n }\n\n return {\n kind: \"timestamp\",\n raw: trimmed,\n historyIndex: index,\n };\n}\n\nfunction extractPatchFailureContext(\n patch: HistoryPatchOp[],\n error: unknown,\n): { patchIndex?: number; op?: string; path?: string; from?: string; reason?: string } {\n const context: { patchIndex?: number; op?: string; path?: string; from?: string; reason?: string } = {};\n if (error instanceof Error && error.message.trim().length > 0) {\n context.reason = error.message.trim();\n }\n if (typeof error !== \"object\" || error === null) {\n return context;\n }\n const candidate = error as {\n index?: unknown;\n operation?: unknown;\n };\n if (typeof candidate.index === \"number\" && Number.isInteger(candidate.index) && candidate.index >= 0) {\n context.patchIndex = candidate.index;\n }\n const operationRecord =\n typeof candidate.operation === \"object\" && candidate.operation !== null\n ? (candidate.operation as { op?: unknown; path?: unknown; from?: unknown })\n : null;\n if (operationRecord && typeof operationRecord.op === \"string\") {\n context.op = operationRecord.op;\n }\n if (operationRecord && typeof operationRecord.path === \"string\") {\n context.path = operationRecord.path;\n }\n if (operationRecord && typeof operationRecord.from === \"string\") {\n context.from = operationRecord.from;\n }\n if ((context.op === undefined || context.path === undefined) && context.patchIndex !== undefined) {\n const fallback = patch[context.patchIndex];\n if (fallback) {\n context.op = context.op ?? fallback.op;\n context.path = context.path ?? fallback.path;\n context.from = context.from ?? fallback.from;\n }\n }\n return context;\n}\n\nfunction applyHistoryPatch(\n current: CanonicalReplayDocument,\n patch: HistoryPatchOp[],\n entryNumber: number,\n entryOp: string,\n): CanonicalReplayDocument {\n try {\n const normalizedPatch = normalizeReplayPatchOps(patch);\n const applied = jsonPatch.applyPatch(\n structuredClone(current),\n normalizedPatch as jsonPatch.Operation[],\n true,\n false,\n ).newDocument as unknown;\n if (\n typeof applied !== \"object\" ||\n applied === null ||\n !(\"metadata\" in applied) ||\n !(\"body\" in applied) ||\n typeof (applied as { body: unknown }).body !== \"string\" ||\n typeof (applied as { metadata: unknown }).metadata !== \"object\" ||\n (applied as { metadata: unknown }).metadata === null\n ) {\n throw new PmCliError(\n `History replay produced an invalid document shape at entry ${entryNumber}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n const replay = applied as { metadata: Record<string, unknown>; body: string };\n return {\n metadata: replay.metadata,\n body: replay.body,\n };\n } catch (error: unknown) {\n if (error instanceof PmCliError) {\n throw error;\n }\n const failureContext = extractPatchFailureContext(patch, error);\n const contextTokens = [\n `history_op=${entryOp}`,\n failureContext.patchIndex !== undefined ? `patch_index=${failureContext.patchIndex}` : null,\n failureContext.op ? `op=${failureContext.op}` : null,\n failureContext.path ? `path=${failureContext.path}` : null,\n failureContext.from ? `from=${failureContext.from}` : null,\n ].filter((token): token is string => token !== null);\n const reasonSuffix = failureContext.reason ? ` ${failureContext.reason}` : \"\";\n throw new PmCliError(\n `Failed to apply history patch at entry ${entryNumber} (${contextTokens.join(\", \")}).${reasonSuffix}`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n}\n\nfunction replayToTarget(history: HistoryEntry[], targetIndex: number): CanonicalReplayDocument {\n let document: CanonicalReplayDocument = structuredClone(EMPTY_REPLAY_DOCUMENT);\n\n for (let i = 0; i <= targetIndex; i += 1) {\n const entry = history[i];\n const beforeHash = replayHash(document);\n if (beforeHash !== entry.before_hash) {\n throw new PmCliError(\n `History hash mismatch before replay at entry ${i + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n\n document = applyHistoryPatch(document, entry.patch, i + 1, entry.op);\n\n const afterHash = replayHash(document);\n if (afterHash !== entry.after_hash) {\n throw new PmCliError(\n `History hash mismatch after replay at entry ${i + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n }\n\n return document;\n}\n\nfunction ensureMaterializedRestoreTarget(\n replayDocument: CanonicalReplayDocument,\n target: ResolvedRestoreTarget,\n): CanonicalReplayDocument {\n if (Object.keys(replayDocument.metadata).length > 0) {\n return replayDocument;\n }\n throw new PmCliError(\n `Restore target ${target.raw} resolves to a deleted state; choose a version or timestamp where the item exists.`,\n EXIT_CODE.USAGE,\n );\n}\n\nfunction replayCurrentDocument(history: HistoryEntry[]): ItemDocument {\n const currentReplay = replayToTarget(history, history.length - 1);\n if (Object.keys(currentReplay.metadata).length === 0) {\n return {\n metadata: {} as ItemMetadata,\n body: currentReplay.body,\n };\n }\n return canonicalDocument({\n metadata: currentReplay.metadata as unknown as ItemMetadata,\n body: currentReplay.body,\n });\n}\n\nasync function resolveRestoreSubject(\n pmRoot: string,\n id: string,\n settings: Awaited<ReturnType<typeof readSettings>>,\n typeToFolder: Record<string, string>,\n): Promise<ResolvedRestoreSubject> {\n const located = await locateItem(pmRoot, id, settings.id_prefix, settings.item_format, typeToFolder);\n if (located) {\n const historyPath = getHistoryPath(pmRoot, located.id);\n const historyPolicy = await enforceHistoryStreamPolicyForItem({\n pmRoot,\n settings,\n itemId: located.id,\n commandLabel: \"restore\",\n });\n return {\n id: located.id,\n historyPath,\n located,\n historyPolicyWarnings: historyPolicy.warnings,\n };\n }\n\n const normalizedId = normalizeItemId(id, settings.id_prefix);\n const rawNormalizedId = normalizeRawItemId(id);\n const candidateIds = normalizedId === rawNormalizedId ? [normalizedId] : [normalizedId, rawNormalizedId];\n for (const candidateId of candidateIds) {\n const historyPath = getHistoryPath(pmRoot, candidateId);\n if (await pathExists(historyPath)) {\n return {\n id: candidateId,\n historyPath,\n located: null,\n historyPolicyWarnings: [],\n };\n }\n }\n\n throw new PmCliError(`Item ${id} not found`, EXIT_CODE.NOT_FOUND);\n}\n\nfunction changedFields(beforeDocument: ItemDocument, afterDocument: ItemDocument): string[] {\n const beforeReplay = toReplayDocument(beforeDocument);\n const afterReplay = toReplayDocument(afterDocument);\n const patch = jsonPatch.compare(beforeReplay, afterReplay) as HistoryPatchOp[];\n const fields = new Set<string>();\n\n for (const op of patch) {\n if (op.path === \"/body\" || op.path.startsWith(\"/body/\")) {\n fields.add(\"body\");\n continue;\n }\n const segment = op.path.replace(/^\\/(?:metadata|front_matter)\\/?/, \"\").split(\"/\")[0];\n fields.add(segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n }\n\n return Array.from(fields).sort((a, b) => a.localeCompare(b));\n}\n\nexport async function runRestore(\n id: string,\n target: string,\n options: RestoreCommandOptions,\n global: GlobalOptions,\n): Promise<RestoreResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);\n }\n\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());\n const subject = await resolveRestoreSubject(pmRoot, id, settings, typeRegistry.type_to_folder);\n const resolvedId = subject.id;\n const historyRawBeforeLock = await readFileIfExists(subject.historyPath);\n const history = await readHistoryEntries(subject.historyPath, resolvedId);\n if (history.length === 0) {\n throw new PmCliError(`No history exists for ${resolvedId}; restore is unavailable.`, EXIT_CODE.NOT_FOUND);\n }\n\n const resolvedTarget = ensureReplayTarget(target, history);\n const replayDocument = ensureMaterializedRestoreTarget(replayToTarget(history, resolvedTarget.historyIndex), resolvedTarget);\n const restoredDocument = canonicalDocument(\n {\n metadata: replayDocument.metadata as unknown as ItemMetadata,\n body: replayDocument.body,\n },\n { schema: settings.schema },\n );\n\n if (restoredDocument.metadata.id !== resolvedId) {\n throw new PmCliError(\n `Restore target resolved to item ${restoredDocument.metadata.id}, expected ${resolvedId}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n const loadedItemBeforeLock = subject.located ? await readLocatedItem(subject.located, { schema: settings.schema }) : null;\n const currentItemRawBeforeLock = loadedItemBeforeLock?.raw ?? null;\n\n const author = resolveAuthor(options.author, settings.author_default);\n const releaseLock = await acquireLock(\n pmRoot,\n resolvedId,\n settings.locks.ttl_seconds,\n author,\n Boolean(options.force),\n settings.governance.force_required_for_stale_lock,\n );\n\n try {\n const historyRawUnderLock = await readFileIfExists(subject.historyPath);\n if (historyRawUnderLock !== historyRawBeforeLock) {\n throw new PmCliError(\n `History for ${resolvedId} changed while waiting for lock; retry restore.`,\n EXIT_CODE.CONFLICT,\n );\n }\n const locatedUnderLock = await locateItem(\n pmRoot,\n resolvedId,\n settings.id_prefix,\n settings.item_format,\n typeRegistry.type_to_folder,\n );\n const loadedItemUnderLock = locatedUnderLock ? await readLocatedItem(locatedUnderLock, { schema: settings.schema }) : null;\n if ((loadedItemUnderLock?.raw ?? null) !== currentItemRawBeforeLock) {\n throw new PmCliError(`Item ${resolvedId} changed while waiting for lock; retry restore.`, EXIT_CODE.CONFLICT);\n }\n\n const existingItemPath = locatedUnderLock?.itemPath ?? null;\n const itemFormat = \"toon\";\n let resolvedCurrentDocument: ItemDocument;\n let resolvedOriginalRaw: string | null = null;\n if (loadedItemUnderLock) {\n resolvedCurrentDocument = loadedItemUnderLock.document;\n resolvedOriginalRaw = loadedItemUnderLock.raw;\n } else {\n resolvedCurrentDocument = replayCurrentDocument(history);\n }\n const assigned = resolvedCurrentDocument.metadata.assignee?.trim();\n const ownershipWarnings: string[] = [];\n const hasOwnershipConflict = assigned && assigned !== author && !options.force;\n if (hasOwnershipConflict) {\n if (settings.governance.ownership_enforcement === \"strict\") {\n throw new PmCliError(\n `Item ${resolvedId} is assigned to ${assigned}. Use --force to override.`,\n EXIT_CODE.CONFLICT,\n );\n }\n if (settings.governance.ownership_enforcement === \"warn\") {\n ownershipWarnings.push(`ownership_warning:assignee_conflict:${resolvedId}:${assigned}`);\n }\n }\n\n const serializedRestore = serializeItemDocument(restoredDocument, { format: itemFormat, schema: settings.schema });\n const restoredItemPath = getItemPath(\n pmRoot,\n restoredDocument.metadata.type,\n resolvedId,\n itemFormat,\n typeRegistry.type_to_folder,\n );\n await writeFileAtomic(restoredItemPath, serializedRestore);\n if (existingItemPath && restoredItemPath !== existingItemPath) {\n await fs.rm(existingItemPath);\n }\n\n const historyEntry = createHistoryEntry({\n nowIso: nowIso(),\n author,\n op: \"restore\",\n before: resolvedCurrentDocument,\n after: restoredDocument,\n message: options.message,\n });\n\n try {\n await appendHistoryEntry(subject.historyPath, historyEntry);\n } catch (error: unknown) {\n if (existingItemPath && resolvedOriginalRaw !== null && restoredItemPath !== existingItemPath) {\n await writeFileAtomic(existingItemPath, resolvedOriginalRaw);\n await fs.rm(restoredItemPath, { force: true });\n } else if (existingItemPath && resolvedOriginalRaw !== null) {\n await writeFileAtomic(existingItemPath, resolvedOriginalRaw);\n } else {\n await fs.rm(restoredItemPath, { force: true });\n }\n throw error;\n }\n const hookWarnings = [\n ...(await runActiveOnWriteHooks({\n path: restoredItemPath,\n scope: \"project\",\n op: \"restore\",\n })),\n ...(await runActiveOnWriteHooks({\n path: subject.historyPath,\n scope: \"project\",\n op: \"restore:history\",\n })),\n ];\n\n const targetEntry = history[resolvedTarget.historyIndex];\n return {\n item: restoredDocument.metadata,\n restored_from: {\n kind: resolvedTarget.kind,\n target: resolvedTarget.raw,\n history_index: resolvedTarget.historyIndex + 1,\n entry_ts: targetEntry.ts,\n entry_op: targetEntry.op,\n },\n changed_fields: changedFields(resolvedCurrentDocument, restoredDocument),\n warnings: [...subject.historyPolicyWarnings, ...ownershipWarnings, ...hookWarnings],\n };\n } finally {\n await releaseLock();\n }\n}\n"],"names":[],"mappings":"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","debugId":"d40fa5ec-9a3f-52de-980b-b83b2e0021d1"}
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="061b3b62-cf94-5aca-9e69-004638268714")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3397f111-3df5-520b-8b2e-ad47976bf2c8")}catch(e){}}();
3
3
  import fs from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { toNonEmptyStringOrUndefined } from "../../core/shared/primitives.js";
@@ -14,6 +14,7 @@ import { executeVectorQuery, resolveVectorStores, } from "../../core/search/vect
14
14
  import { buildEventCorpus, buildPlanFlatCorpus, buildReminderCorpus } from "../../core/search/corpus.js";
15
15
  import { pathExists } from "../../core/fs/fs-utils.js";
16
16
  import { parseItemDocument } from "../../core/item/item-format.js";
17
+ import { toItemRecord } from "../../core/item/item-record.js";
17
18
  import { isTerminalStatus } from "../../core/item/status.js";
18
19
  import { collectRuntimeFilterValues, matchesRuntimeFilters } from "../../core/schema/runtime-field-filters.js";
19
20
  import { resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, } from "../../core/schema/runtime-schema.js";
@@ -586,8 +587,6 @@ function emptySearchResult(query, mode, options, includeLinked, scoreThreshold,
586
587
  score_threshold: scoreThreshold,
587
588
  hybrid_semantic_weight: mode === "hybrid" ? hybridSemanticWeight : null,
588
589
  limit: options.limit ?? null,
589
- projection: projection.mode,
590
- fields: projectionFields,
591
590
  },
592
591
  projection: {
593
592
  mode: projection.mode,
@@ -854,11 +853,11 @@ function readSearchFieldValue(hit, field) {
854
853
  if (itemKey.length === 0) {
855
854
  return null;
856
855
  }
857
- const itemRecord = hit.item;
856
+ const itemRecord = toItemRecord(hit.item);
858
857
  return itemRecord[itemKey] ?? null;
859
858
  }
860
859
  const hitRecord = hit;
861
- const itemRecord = hit.item;
860
+ const itemRecord = toItemRecord(hit.item);
862
861
  if (Object.prototype.hasOwnProperty.call(itemRecord, normalized)) {
863
862
  return itemRecord[normalized] ?? null;
864
863
  }
@@ -1040,8 +1039,6 @@ export async function runSearch(query, options, global) {
1040
1039
  hybrid_semantic_weight: effectiveMode === "hybrid" ? hybridSemanticWeight : null,
1041
1040
  limit: options.limit ?? null,
1042
1041
  runtime_filters: runtimeFieldFilters,
1043
- projection: projection.mode,
1044
- fields: projectionFields,
1045
1042
  },
1046
1043
  projection: {
1047
1044
  mode: projection.mode,
@@ -1052,4 +1049,4 @@ export async function runSearch(query, options, global) {
1052
1049
  };
1053
1050
  }
1054
1051
  //# sourceMappingURL=search.js.map
1055
- //# debugId=061b3b62-cf94-5aca-9e69-004638268714
1052
+ //# debugId=3397f111-3df5-520b-8b2e-ad47976bf2c8