@unbrained/pm-cli 2026.8.19 → 2026.8.21

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 (229) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +41 -0
  3. package/dist/cli/error-guidance.d.ts +20 -0
  4. package/dist/cli/error-guidance.js +29 -30
  5. package/dist/cli/register-list-query.js +12 -10
  6. package/dist/cli/register-structured-mutation.d.ts +2 -0
  7. package/dist/cli/register-structured-mutation.js +29 -6
  8. package/dist/cli-bundle/bundle-manifest.json +156 -148
  9. package/dist/cli-bundle/chunks/chunk-2MA6ZQVZ.js +197 -0
  10. package/dist/cli-bundle/chunks/{chunk-4NRRH7AM.js → chunk-3AFAUHUE.js} +2 -2
  11. package/dist/cli-bundle/chunks/chunk-7VHZS727.js +5 -0
  12. package/dist/cli-bundle/chunks/chunk-BKYB45NQ.js +2092 -0
  13. package/dist/cli-bundle/chunks/{chunk-BHYMXLAE.js → chunk-BUNIEJNE.js} +2 -2
  14. package/dist/cli-bundle/chunks/{chunk-QXSH7BLM.js → chunk-JSLOFXGA.js} +3 -3
  15. package/dist/cli-bundle/chunks/chunk-LARJJ3RK.js +3 -0
  16. package/dist/cli-bundle/chunks/{chunk-TOXJM4WA.js → chunk-LOVTQ52Z.js} +2 -2
  17. package/dist/cli-bundle/chunks/chunk-N3DSV4CH.js +77 -0
  18. package/dist/cli-bundle/chunks/chunk-OCLPLFAY.js +35 -0
  19. package/dist/cli-bundle/chunks/chunk-S4IRYKBU.js +13 -0
  20. package/dist/cli-bundle/chunks/register-list-query-F57EWDEF.js +11 -0
  21. package/dist/cli-bundle/chunks/{register-mutation-AUWVCW4M.js → register-mutation-7IY2D5KO.js} +20 -20
  22. package/dist/cli-bundle/chunks/{register-operations-PZQPHXW5.js → register-operations-FALL3YTU.js} +2 -2
  23. package/dist/cli-bundle/chunks/{register-setup-I4LUHGVW.js → register-setup-HXU7IZZD.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/chunk-2NIY5NKG.js +18 -0
  25. package/dist/cli-bundle/focused-chunks/{chunk-US7VEYZG.js → chunk-4ERLO7QD.js} +2 -2
  26. package/dist/cli-bundle/focused-chunks/chunk-7WZRLCYF.js +50 -0
  27. package/dist/cli-bundle/focused-chunks/{chunk-MCZXYZAF.js → chunk-CKKQSJNN.js} +2 -2
  28. package/dist/cli-bundle/focused-chunks/chunk-EEFKYMDR.js +16 -0
  29. package/dist/cli-bundle/focused-chunks/{chunk-ZBIQQYMI.js → chunk-F2A56DHV.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-ESISGDAY.js → chunk-F4YEW5I2.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/{chunk-ODHQEECS.js → chunk-FH6DYED3.js} +2 -2
  32. package/dist/cli-bundle/focused-chunks/chunk-FJ22HNRP.js +2 -0
  33. package/dist/cli-bundle/focused-chunks/chunk-FV5ACOK7.js +2 -0
  34. package/dist/cli-bundle/focused-chunks/chunk-JEAVFOWM.js +2 -0
  35. package/dist/cli-bundle/focused-chunks/{chunk-EXBCLIBU.js → chunk-KDNG7TKQ.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/chunk-NJ63LOP6.js +155 -0
  37. package/dist/cli-bundle/focused-chunks/chunk-NXRTQ7HI.js +2 -0
  38. package/dist/cli-bundle/focused-chunks/{chunk-JDOMQ7VQ.js → chunk-TJ7EMJ46.js} +3 -3
  39. package/dist/cli-bundle/focused-chunks/chunk-UZE7XUZK.js +2 -0
  40. package/dist/cli-bundle/focused-chunks/{chunk-DKPLYW3L.js → chunk-YKBKIEAJ.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/{chunk-VXDSU5MC.js → chunk-ZOSEELYJ.js} +2 -2
  42. package/dist/cli-bundle/main.js +12 -12
  43. package/dist/cli-bundle/sdk-authoring.js +1 -1
  44. package/dist/cli-bundle/sdk-contracts.js +2 -2
  45. package/dist/cli-bundle/sdk-core.js +41 -41
  46. package/dist/cli-bundle/sdk-governance.js +1 -1
  47. package/dist/cli-bundle/sdk-graph.js +1 -1
  48. package/dist/cli-bundle/sdk-merge.js +32 -32
  49. package/dist/cli-bundle/sdk-query.js +1 -1
  50. package/dist/cli-bundle/sdk-runtime.js +1 -1
  51. package/dist/cli-bundle/sdk-testing.js +1 -1
  52. package/dist/cli-bundle/sdk.js +5 -5
  53. package/dist/core/output/mutation-projection.js +26 -2
  54. package/dist/core/shared/constants.d.ts +1 -5
  55. package/dist/core/shared/constants.js +3 -81
  56. package/dist/core/shared/errors.d.ts +16 -0
  57. package/dist/core/shared/errors.js +2 -2
  58. package/dist/core/shared/item-metadata-contract.d.ts +14 -0
  59. package/dist/core/shared/item-metadata-contract.js +90 -0
  60. package/dist/core/store/item-store.d.ts +60 -0
  61. package/dist/core/store/item-store.js +26 -94
  62. package/dist/core/store/tracker-preflight.d.ts +7 -0
  63. package/dist/core/store/tracker-preflight.js +142 -0
  64. package/dist/sdk/agent/closed-domain-contracts.d.ts +25 -0
  65. package/dist/sdk/agent/closed-domain-contracts.js +140 -0
  66. package/dist/sdk/agent/refusal-closure.d.ts +13 -1
  67. package/dist/sdk/agent/refusal-closure.js +45 -3
  68. package/dist/sdk/agent/refusal-reachability.d.ts +26 -0
  69. package/dist/sdk/agent/refusal-reachability.js +26 -2
  70. package/dist/sdk/agent/tracker-preflight-contracts.d.ts +63 -0
  71. package/dist/sdk/agent/tracker-preflight-contracts.js +127 -0
  72. package/dist/sdk/agent-capability-contracts.js +6 -11
  73. package/dist/sdk/annotations.js +6 -7
  74. package/dist/sdk/cli-contracts/completeness.js +8 -2
  75. package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -2
  76. package/dist/sdk/cli-contracts/enum-contracts.js +16 -6
  77. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  78. package/dist/sdk/cli-contracts/flag-contracts.js +11 -2
  79. package/dist/sdk/cli-contracts/flag-lexicon-contracts.d.ts +19 -2
  80. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +105 -5
  81. package/dist/sdk/cli-contracts/grammar-contracts.d.ts +2 -2
  82. package/dist/sdk/cli-contracts/grammar-contracts.js +5 -2
  83. package/dist/sdk/cli-contracts/runtime-contracts.js +7 -3
  84. package/dist/sdk/cli-contracts/tool-schema.js +7 -2
  85. package/dist/sdk/cli-contracts.d.ts +2 -2
  86. package/dist/sdk/cli-contracts.js +4 -4
  87. package/dist/sdk/config.d.ts +5 -0
  88. package/dist/sdk/config.js +5 -5
  89. package/dist/sdk/context-intent-runtime.js +7 -4
  90. package/dist/sdk/contracts.d.ts +2 -0
  91. package/dist/sdk/contracts.js +4 -2
  92. package/dist/sdk/core.d.ts +1 -1
  93. package/dist/sdk/core.js +3 -3
  94. package/dist/sdk/dependencies.js +5 -7
  95. package/dist/sdk/dependency-flag-validation.d.ts +1 -1
  96. package/dist/sdk/dependency-flag-validation.js +10 -4
  97. package/dist/sdk/environment/tracker-preflight.d.ts +6 -0
  98. package/dist/sdk/environment/tracker-preflight.js +10 -0
  99. package/dist/sdk/eval.js +5 -7
  100. package/dist/sdk/files.js +6 -10
  101. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +110 -2
  102. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +179 -46
  103. package/dist/sdk/governance/assurance.d.ts +36 -2
  104. package/dist/sdk/governance/assurance.js +184 -10
  105. package/dist/sdk/governance/gc.js +5 -6
  106. package/dist/sdk/governance/health.js +5 -6
  107. package/dist/sdk/governance/reindex.js +5 -6
  108. package/dist/sdk/governance/validate.d.ts +1 -2
  109. package/dist/sdk/governance/validate.js +6 -12
  110. package/dist/sdk/graph/governance.d.ts +7 -5
  111. package/dist/sdk/graph/governance.js +32 -16
  112. package/dist/sdk/graph/run.js +5 -7
  113. package/dist/sdk/graph/traversal.js +14 -5
  114. package/dist/sdk/history-compact.js +6 -9
  115. package/dist/sdk/history-read.js +5 -7
  116. package/dist/sdk/history-redact.js +5 -6
  117. package/dist/sdk/history-repair.js +6 -9
  118. package/dist/sdk/improvement-ledger.js +7 -10
  119. package/dist/sdk/index.d.ts +7 -3
  120. package/dist/sdk/index.js +8 -4
  121. package/dist/sdk/init-agent-guidance.d.ts +5 -3
  122. package/dist/sdk/init-agent-guidance.js +69 -9
  123. package/dist/sdk/lifecycle/append.d.ts +0 -5
  124. package/dist/sdk/lifecycle/append.js +5 -6
  125. package/dist/sdk/lifecycle/claim.d.ts +0 -5
  126. package/dist/sdk/lifecycle/claim.js +6 -9
  127. package/dist/sdk/lifecycle/close-many.d.ts +0 -5
  128. package/dist/sdk/lifecycle/close-many.js +5 -6
  129. package/dist/sdk/lifecycle/close.d.ts +0 -5
  130. package/dist/sdk/lifecycle/close.js +5 -6
  131. package/dist/sdk/lifecycle/copy.d.ts +0 -5
  132. package/dist/sdk/lifecycle/copy.js +5 -6
  133. package/dist/sdk/lifecycle/create.d.ts +0 -5
  134. package/dist/sdk/lifecycle/create.js +5 -9
  135. package/dist/sdk/lifecycle/delete.js +5 -6
  136. package/dist/sdk/lifecycle/focus.d.ts +0 -5
  137. package/dist/sdk/lifecycle/focus.js +5 -6
  138. package/dist/sdk/lifecycle/mcp-actions.d.ts +18 -0
  139. package/dist/sdk/lifecycle/mcp-actions.js +52 -0
  140. package/dist/sdk/lifecycle/plan.d.ts +0 -5
  141. package/dist/sdk/lifecycle/plan.js +5 -6
  142. package/dist/sdk/lifecycle/reopen.d.ts +44 -0
  143. package/dist/sdk/lifecycle/reopen.js +69 -0
  144. package/dist/sdk/lifecycle/restore.js +5 -6
  145. package/dist/sdk/lifecycle/update-many.d.ts +0 -5
  146. package/dist/sdk/lifecycle/update-many.js +5 -6
  147. package/dist/sdk/lifecycle/update.d.ts +31 -5
  148. package/dist/sdk/lifecycle/update.js +140 -19
  149. package/dist/sdk/linked-artifacts.js +6 -7
  150. package/dist/sdk/merge/install.js +5 -6
  151. package/dist/sdk/mutation-events.js +5 -7
  152. package/dist/sdk/package-import-adapters.js +6 -8
  153. package/dist/sdk/profile.js +6 -7
  154. package/dist/sdk/query/activity.js +5 -6
  155. package/dist/sdk/query/calendar.js +5 -6
  156. package/dist/sdk/query/get.d.ts +1 -6
  157. package/dist/sdk/query/get.js +20 -55
  158. package/dist/sdk/query/history.d.ts +0 -5
  159. package/dist/sdk/query/history.js +5 -6
  160. package/dist/sdk/query/list.d.ts +7 -21
  161. package/dist/sdk/query/list.js +38 -54
  162. package/dist/sdk/query/projection-contracts.d.ts +33 -0
  163. package/dist/sdk/query/projection-contracts.js +185 -0
  164. package/dist/sdk/query/search-contracts.d.ts +2 -1
  165. package/dist/sdk/query/search-contracts.js +18 -87
  166. package/dist/sdk/query/search.d.ts +15 -0
  167. package/dist/sdk/query/search.js +34 -10
  168. package/dist/sdk/relationship-kinds/contract.d.ts +8 -0
  169. package/dist/sdk/relationship-kinds/contract.js +13 -13
  170. package/dist/sdk/relationships.d.ts +1 -1
  171. package/dist/sdk/relationships.js +20 -2
  172. package/dist/sdk/runtime-primitives.d.ts +1 -1
  173. package/dist/sdk/runtime-primitives.js +3 -3
  174. package/dist/sdk/runtime.d.ts +6 -0
  175. package/dist/sdk/runtime.js +18 -14
  176. package/dist/sdk/schema-migration.js +6 -7
  177. package/dist/sdk/schema.js +5 -6
  178. package/dist/sdk/similarity.d.ts +13 -0
  179. package/dist/sdk/similarity.js +32 -6
  180. package/dist/sdk/stats.js +5 -8
  181. package/dist/sdk/templates.js +5 -6
  182. package/dist/sdk/test/batch.js +5 -7
  183. package/dist/sdk/test/execution.js +4 -5
  184. package/dist/sdk/test/runs.js +5 -7
  185. package/docs/AGENT_UX_CONTRACTS.md +8 -1
  186. package/docs/COMMANDS.md +13 -1
  187. package/docs/DEPENDENCY_KIND_CONTRACT.md +12 -1
  188. package/docs/README.md +1 -0
  189. package/docs/RECURRENCE_RECOVERY_CONTRACTS.md +151 -0
  190. package/docs/RELATIONSHIP_GRAPH.md +92 -10
  191. package/docs/SDK.md +10 -2
  192. package/docs/SDK_CONTEXT_INTEGRITY.md +45 -0
  193. package/docs/SDK_PRIMITIVE_INVENTORY.md +15 -1
  194. package/docs/generated/AGENT_COMMAND_SURFACE.md +1 -1
  195. package/docs/performance/sdk-entrypoint-import-costs.md +14 -21
  196. package/marketplace.json +2 -2
  197. package/package.json +5 -5
  198. package/packages/pm-beads/package.json +1 -1
  199. package/packages/pm-calendar/package.json +1 -1
  200. package/packages/pm-command-kit/package.json +1 -1
  201. package/packages/pm-digital-twin/package.json +1 -1
  202. package/packages/pm-governance-audit/package.json +1 -1
  203. package/packages/pm-guide-shell/package.json +1 -1
  204. package/packages/pm-kanban/package.json +1 -1
  205. package/packages/pm-lifecycle-hooks/package.json +1 -1
  206. package/packages/pm-linked-test-adapters/package.json +1 -1
  207. package/packages/pm-search-advanced/package.json +1 -1
  208. package/packages/pm-templates/package.json +1 -1
  209. package/packages/pm-todos/package.json +1 -1
  210. package/packages/pm-vcs/package.json +1 -1
  211. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  212. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  213. package/sdk/public-surface.json +640 -44
  214. package/dist/cli-bundle/chunks/chunk-4THEB6PD.js +0 -13
  215. package/dist/cli-bundle/chunks/chunk-GWMXAQOD.js +0 -197
  216. package/dist/cli-bundle/chunks/chunk-HVFQTLYM.js +0 -35
  217. package/dist/cli-bundle/chunks/chunk-OI4XI562.js +0 -5
  218. package/dist/cli-bundle/chunks/chunk-OIOKV6NO.js +0 -2092
  219. package/dist/cli-bundle/chunks/chunk-SARFF5H5.js +0 -3
  220. package/dist/cli-bundle/chunks/chunk-YBMRWW4E.js +0 -77
  221. package/dist/cli-bundle/chunks/register-list-query-Y56KINDU.js +0 -11
  222. package/dist/cli-bundle/focused-chunks/chunk-34QBIYZI.js +0 -155
  223. package/dist/cli-bundle/focused-chunks/chunk-BJRYFVSH.js +0 -2
  224. package/dist/cli-bundle/focused-chunks/chunk-EF6ZS5GH.js +0 -50
  225. package/dist/cli-bundle/focused-chunks/chunk-L623ZPNK.js +0 -2
  226. package/dist/cli-bundle/focused-chunks/chunk-PRHY2IMX.js +0 -18
  227. package/dist/cli-bundle/focused-chunks/chunk-RZU5U6Q7.js +0 -2
  228. package/dist/cli-bundle/focused-chunks/chunk-YBMGXBFV.js +0 -16
  229. package/dist/cli-bundle/focused-chunks/chunk-YLVBJ6GF.js +0 -2
@@ -4,83 +4,13 @@
4
4
  * Owns search input parsing, output projection contracts, and tuning defaults.
5
5
  */
6
6
 
7
- !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]="e737cdf9-734c-5010-864f-60e8052dd9c1")}catch(e){}}();
7
+ !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]="d20ab01b-a8ae-5fe8-988a-d05fe87951f6")}catch(e){}}();
8
8
  import { coerceNumberInRange } from "../../core/shared/primitives.js";
9
- import { EXIT_CODE } from "../../core/shared/constants.js";
10
- import { PmCliError } from "../../core/shared/errors.js";
11
9
  import { resolveIsoOrRelative } from "../../core/shared/time.js";
12
10
  import { renderPmCommand } from "../command-line.js";
13
- const DEFAULT_COMPACT_SEARCH_FIELDS = [
14
- "id",
15
- "title",
16
- "status",
17
- "type",
18
- "priority",
19
- "updated_at",
20
- "score",
21
- "matched_fields",
22
- ];
23
- const SEARCH_HIT_FIELD_KEYS = new Set([
24
- "score",
25
- "matched_fields",
26
- "highlights",
27
- ]);
28
- const SEARCH_ITEM_FIELD_KEYS = new Set([
29
- "id",
30
- "title",
31
- "description",
32
- "type",
33
- "status",
34
- "priority",
35
- "tags",
36
- "created_at",
37
- "updated_at",
38
- "deadline",
39
- "assignee",
40
- "author",
41
- "estimated_minutes",
42
- "acceptance_criteria",
43
- "dependencies",
44
- "comments",
45
- "notes",
46
- "learnings",
47
- "reminders",
48
- "events",
49
- "files",
50
- "tests",
51
- "docs",
52
- "close_reason",
53
- "parent",
54
- "reviewer",
55
- "risk",
56
- "confidence",
57
- "sprint",
58
- "release",
59
- "blocked_by",
60
- "blocked_reason",
61
- "reporter",
62
- "severity",
63
- "environment",
64
- "repro_steps",
65
- "resolution",
66
- "expected_result",
67
- "actual_result",
68
- "affected_version",
69
- "fixed_version",
70
- "component",
71
- "regression",
72
- "customer_impact",
73
- "definition_of_ready",
74
- "order",
75
- "rank",
76
- "goal",
77
- "objective",
78
- "value",
79
- "impact",
80
- "outcome",
81
- "why_now",
82
- "plan",
83
- ]);
11
+ import { EXIT_CODE, PmCliError } from "../runtime-primitives.js";
12
+ import { DEFAULT_COMPACT_SEARCH_FIELDS, listSearchProjectionFields, } from "./projection-contracts.js";
13
+ export { DEFAULT_COMPACT_SEARCH_FIELDS, SEARCH_HIT_FIELD_KEYS, SEARCH_ITEM_FIELD_KEYS, listSearchProjectionFields, } from "./projection-contracts.js";
84
14
  /** Parse the configured search execution mode. */
85
15
  export function parseSearchMode(raw) {
86
16
  if (raw === undefined)
@@ -155,7 +85,7 @@ function parseFieldSelectors(raw) {
155
85
  return [...new Set(selectors)];
156
86
  }
157
87
  /** Resolve mutually exclusive compact, full, or explicit-field projection. */
158
- export function parseSearchProjection(options) {
88
+ export function parseSearchProjection(options, query = "<query>") {
159
89
  const compactRequested = options.compact === true;
160
90
  const fullRequested = options.full === true;
161
91
  const fieldSelectors = parseFieldSelectors(options.fields);
@@ -163,7 +93,13 @@ export function parseSearchProjection(options) {
163
93
  Number(fullRequested) +
164
94
  Number(fieldSelectors !== undefined);
165
95
  if (enabledModes > 1) {
166
- throw new PmCliError("Search projection options are mutually exclusive. Use one of --compact, --full, or --fields.", EXIT_CODE.USAGE);
96
+ throw new PmCliError("Search projection options are mutually exclusive. Use one of --compact, --full, or --fields.", EXIT_CODE.USAGE, {
97
+ code: "projection_options_mutually_exclusive",
98
+ recovery: {
99
+ suggested_retry: renderPmCommand(["search", query, "--full"]),
100
+ suggested_retry_args: ["search", query, "--full"],
101
+ },
102
+ });
167
103
  }
168
104
  if (compactRequested) {
169
105
  return { mode: "compact", fields: [...DEFAULT_COMPACT_SEARCH_FIELDS] };
@@ -178,20 +114,14 @@ export function parseSearchProjection(options) {
178
114
  export function validateSearchProjectionFields(projection, runtimeFieldRegistry, query = "<query>") {
179
115
  if (projection.mode !== "fields")
180
116
  return;
181
- const runtimeKeys = new Set(runtimeFieldRegistry.definitions.flatMap((field) => [
117
+ const allowedValues = listSearchProjectionFields(runtimeFieldRegistry.definitions.flatMap((field) => [
182
118
  field.key,
183
119
  field.metadata_key,
184
120
  ]));
185
- const allowedValues = new Set([
186
- ...SEARCH_HIT_FIELD_KEYS,
187
- ...SEARCH_ITEM_FIELD_KEYS,
188
- ...[...SEARCH_ITEM_FIELD_KEYS].map((field) => `item.${field}`),
189
- ...runtimeKeys,
190
- ...[...runtimeKeys].map((field) => `item.${field}`),
191
- ]);
121
+ const allowed = new Set(allowedValues);
192
122
  const unknown = projection.fields.filter((field) => {
193
123
  const normalized = field.trim();
194
- return !allowedValues.has(normalized);
124
+ return !allowed.has(normalized);
195
125
  });
196
126
  if (unknown.length > 0) {
197
127
  const suggestedRetryArguments = [
@@ -201,6 +131,7 @@ export function validateSearchProjectionFields(projection, runtimeFieldRegistry,
201
131
  "id,title,status,score",
202
132
  ];
203
133
  throw new PmCliError(`Unknown search --fields value(s): ${unknown.join(", ")}`, EXIT_CODE.USAGE, {
134
+ code: "unknown_field_projection",
204
135
  examples: [
205
136
  "pm search <query> --fields id,title,status,score",
206
137
  "pm search <query> --fields id,title,item.description,matched_fields",
@@ -209,7 +140,7 @@ export function validateSearchProjectionFields(projection, runtimeFieldRegistry,
209
140
  "Use item.<field> for explicit item metadata fields, or run pm search --help for projection examples.",
210
141
  ],
211
142
  recovery: {
212
- allowed_values: [...allowedValues].sort(),
143
+ allowed_values: allowedValues,
213
144
  suggested_retry: renderPmCommand(suggestedRetryArguments),
214
145
  suggested_retry_args: suggestedRetryArguments,
215
146
  },
@@ -297,4 +228,4 @@ export function resolveSearchTuning(settings) {
297
228
  };
298
229
  }
299
230
  //# sourceMappingURL=search-contracts.js.map
300
- //# debugId=e737cdf9-734c-5010-864f-60e8052dd9c1
231
+ //# debugId=d20ab01b-a8ae-5fe8-988a-d05fe87951f6
@@ -183,8 +183,23 @@ export declare function collectErrorCauseCodes(error: unknown): string;
183
183
  */
184
184
  export declare function classifyImplicitSemanticFallbackReason(error: unknown): ImplicitSemanticFallbackReason;
185
185
  declare function buildExplicitSemanticFallbackWarning(requestedMode: SearchMode, error: unknown): string;
186
+ interface VectorIndexRecoveryRegistrations {
187
+ commands?: readonly {
188
+ command: string;
189
+ }[];
190
+ }
191
+ interface VectorIndexRecovery {
192
+ command: string;
193
+ args: string[];
194
+ follow_up_command?: string;
195
+ follow_up_args?: string[];
196
+ }
197
+ /** Resolve an executable reindex path from the active extension capability surface. */
198
+ export declare function resolveVectorIndexRecovery(registrations: VectorIndexRecoveryRegistrations | null): VectorIndexRecovery;
186
199
  /** Compare the vectorization-status ledger against the filtered corpus and, when the vector index is behind, emit a one-line stderr warning plus a structured `vector_index_stale:N` entry in the JSON warnings array. Best-effort: ledger read failures fall through silently — the existing semantic/hybrid fallback paths cover backend errors. */
187
200
  declare function maybeEmitVectorIndexStaleWarning(pmRoot: string, filteredDocuments: ItemDocument[], warnings: string[]): Promise<void>;
201
+ /** Format token-efficient vector-index staleness and executable recovery warnings. */
202
+ export declare function formatVectorIndexRecoveryWarnings(staleCount: number, recovery: VectorIndexRecovery): string[];
188
203
  /** Public contract for test only search command, shared by SDK and presentation-layer consumers. */
189
204
  export declare const _testOnlySearchCommand: {
190
205
  applyFilters: typeof applyFilters;
@@ -4,7 +4,8 @@
4
4
  * Implements the pm search command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !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]="0582c462-43fc-563c-b209-d6e3c39948f4")}catch(e){}}();
7
+ !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]="a4117e19-af3e-50f5-b3cc-86c39aa4b439")}catch(e){}}();
8
+ import { assertInitializedTracker } from "../environment/tracker-preflight.js";
8
9
  import fs from "node:fs/promises";
9
10
  import path from "node:path";
10
11
  import { toNonEmptyStringOrUndefined } from "../../core/shared/primitives.js";
@@ -23,7 +24,6 @@ import { readVectorizationStatusLedger } from "../../core/search/cache.js";
23
24
  import { buildEventCorpus, buildPlanFlatCorpus, buildReminderCorpus, buildSearchCorpus, resolveSearchCorpusFields, } from "../../core/search/corpus.js";
24
25
  import { buildBm25Index, flattenSearchCorpusText, resolveBm25Params, scoreBm25Query, tokenizeBm25, } from "../../core/search/bm25.js";
25
26
  import { collectStaleVectorizationIds } from "../../core/search/staleness.js";
26
- import { pathExists } from "../../core/fs/fs-utils.js";
27
27
  import { parseItemDocument } from "../../core/item/item-format.js";
28
28
  import { toItemRecord } from "../../core/item/item-record.js";
29
29
  import { isTerminalStatus } from "../../core/item/status.js";
@@ -40,7 +40,7 @@ import { tokenizeAlphaNumeric } from "../../core/shared/text-normalization.js";
40
40
  import { compareTimestampStrings, matchesTimestampFilters, nowIso, } from "../../core/shared/time.js";
41
41
  import { listAllDocumentCandidatesCached } from "../../core/store/item-metadata-cache.js";
42
42
  import { listAllItemMetadata } from "../../core/store/item-store.js";
43
- import { getItemPath, getSettingsPath, resolveGlobalPmRoot, resolvePmRoot, } from "../../core/store/paths.js";
43
+ import { getItemPath, resolveGlobalPmRoot, resolvePmRoot, } from "../../core/store/paths.js";
44
44
  import { readSettings } from "../../core/store/settings.js";
45
45
  import { resolveSearchPage } from "./search-pagination.js";
46
46
  import { normalizeSearchPhrase, parseMinScoreOverride, parseSearchBoolean, parseSearchDeadline, parseSearchMatchMode, parseSearchMode, parseSearchProjection, parseSearchTokens, parseSemanticWeightOverride, parseTimestampWindow, resolveHybridSemanticWeight, resolveSearchMaxResults, resolveSearchScoreThreshold, resolveSearchTuning, validateSearchProjectionFields, } from "./search-contracts.js";
@@ -128,6 +128,21 @@ function buildExplicitSemanticFallbackWarning(requestedMode, error) {
128
128
  const reason = classifyImplicitSemanticFallbackReason(error);
129
129
  return `search_${requestedMode}_fallback:${reason}:using_keyword_mode`;
130
130
  }
131
+ /** Resolve an executable reindex path from the active extension capability surface. */
132
+ export function resolveVectorIndexRecovery(registrations) {
133
+ const hasReindex = registrations?.commands?.some((registration) => registration.command.trim() === "reindex") === true;
134
+ return hasReindex
135
+ ? {
136
+ command: "pm reindex --mode hybrid",
137
+ args: ["reindex", "--mode", "hybrid"],
138
+ }
139
+ : {
140
+ command: "pm install search-advanced --project",
141
+ args: ["install", "search-advanced", "--project"],
142
+ follow_up_command: "pm reindex --mode hybrid",
143
+ follow_up_args: ["reindex", "--mode", "hybrid"],
144
+ };
145
+ }
131
146
  /** Compare the vectorization-status ledger against the filtered corpus and, when the vector index is behind, emit a one-line stderr warning plus a structured `vector_index_stale:N` entry in the JSON warnings array. Best-effort: ledger read failures fall through silently — the existing semantic/hybrid fallback paths cover backend errors. */
132
147
  async function maybeEmitVectorIndexStaleWarning(pmRoot, filteredDocuments, warnings) {
133
148
  try {
@@ -142,15 +157,26 @@ async function maybeEmitVectorIndexStaleWarning(pmRoot, filteredDocuments, warni
142
157
  if (staleIds.length === 0) {
143
158
  return;
144
159
  }
145
- warnings.push(`vector_index_stale:${staleIds.length}`);
160
+ const recovery = resolveVectorIndexRecovery(getActiveExtensionRegistrations());
161
+ warnings.push(...formatVectorIndexRecoveryWarnings(staleIds.length, recovery));
146
162
  /* c8 ignore start -- singular/plural warning text branches are cosmetic and validated in integration UX tests */
147
- process.stderr.write(`[pm] warning: ${staleIds.length} item${staleIds.length === 1 ? " is" : "s are"} new or modified since the last reindex and ${staleIds.length === 1 ? "is" : "are"} NOT in the semantic index yet — they will be missing from semantic/hybrid results until you run 'pm reindex --mode hybrid'. (Write-time embedding is governed by search.mutation_refresh_policy; staleness means the embed was skipped, failed, or the backend was unreachable.)\n`);
163
+ process.stderr.write(`[pm] warning: ${staleIds.length} item${staleIds.length === 1 ? " is" : "s are"} new or modified since the last reindex and ${staleIds.length === 1 ? "is" : "are"} NOT in the semantic index yet — run '${recovery.command}'${recovery.follow_up_command ? `, then '${recovery.follow_up_command}'` : ""}. (Write-time embedding is governed by search.mutation_refresh_policy; staleness means the embed was skipped, failed, or the backend was unreachable.)\n`);
148
164
  /* c8 ignore stop */
149
165
  }
150
166
  catch {
151
167
  // Best-effort: missing/unreadable ledger is not a query-blocking concern.
152
168
  }
153
169
  }
170
+ /** Format token-efficient vector-index staleness and executable recovery warnings. */
171
+ export function formatVectorIndexRecoveryWarnings(staleCount, recovery) {
172
+ return [
173
+ `vector_index_stale:${staleCount}`,
174
+ `vector_index_recovery:${recovery.args.join(" ")}`,
175
+ ...(recovery.follow_up_args
176
+ ? [`vector_index_recovery_follow_up:${recovery.follow_up_args.join(" ")}`]
177
+ : []),
178
+ ];
179
+ }
154
180
  /** Public contract for test only search command, shared by SDK and presentation-layer consumers. */
155
181
  export const _testOnlySearchCommand = {
156
182
  applyFilters,
@@ -1539,15 +1565,13 @@ function prepareSearchInput(rawQuery, rawOptions) {
1539
1565
  tokens: parseSearchTokens(query),
1540
1566
  normalizedQuery: normalizeSearchPhrase(query),
1541
1567
  limit: parseLimit(options.limit),
1542
- projection: parseSearchProjection(options),
1568
+ projection: parseSearchProjection(options, rawQuery),
1543
1569
  modeWasExplicit: typeof options.mode === "string" && options.mode.trim().length > 0,
1544
1570
  };
1545
1571
  }
1546
1572
  async function resolveSearchRuntimeContext(prepared, global) {
1547
1573
  const pmRoot = resolvePmRoot(process.cwd(), global.path);
1548
- if (!(await pathExists(getSettingsPath(pmRoot)))) {
1549
- throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
1550
- }
1574
+ await assertInitializedTracker(pmRoot);
1551
1575
  const storedSettings = await readSettings(pmRoot);
1552
1576
  const settings = resolveSettingsWithSemanticRuntimeDefaults(storedSettings).settings;
1553
1577
  const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
@@ -1961,4 +1985,4 @@ export async function runSearch(rawQuery, rawOptions, global) {
1961
1985
  return withSearchWorkspaceMemory(buildSearchResultForHits(response, projectedItems, total, page.limited.length, effectiveProjection, page.pageExtras), workspaceMemoryResult);
1962
1986
  }
1963
1987
  //# sourceMappingURL=search.js.map
1964
- //# debugId=0582c462-43fc-563c-b209-d6e3c39948f4
1988
+ //# debugId=a4117e19-af3e-50f5-b3cc-86c39aa4b439
@@ -15,12 +15,20 @@ export type RelationshipTemporalOrder = "source_after_target";
15
15
  export type RelationshipPrecedence = "source_before_target" | "target_before_source";
16
16
  /** Endpoint that represents the structural parent for hierarchy kinds. */
17
17
  export type RelationshipHierarchyDirection = "source_parent" | "target_parent";
18
+ /** Closure family that gives a relationship its default traversal vocabulary. */
19
+ export type RelationshipTraversalFamily = "hierarchy" | "ordering" | "semantic" | "association";
20
+ /** Direction in which an edge can carry a node toward a declared outcome. */
21
+ export type RelationshipOutcomeTraversal = "source_to_target" | "target_to_source" | "both";
18
22
  /** Versioned semantic definition for a built-in or application-defined edge kind. */
19
23
  export interface RelationshipKindDefinition {
20
24
  /** Canonical, case-insensitive kind identifier. */
21
25
  kind: string;
22
26
  /** Whether traversing source to target has distinct meaning from the reverse. */
23
27
  direction: RelationshipDirection;
28
+ /** Default closure vocabulary; omitted custom definitions infer it from legacy flags. */
29
+ traversal?: RelationshipTraversalFamily;
30
+ /** Direction this kind contributes to typed outcome reachability, when any. */
31
+ outcomeTraversal?: RelationshipOutcomeTraversal;
24
32
  /** Optional canonical kind used when traversing a directed edge in reverse. */
25
33
  inverse?: string;
26
34
  /** Whether the kind participates in execution-order cycle checks. */
@@ -5,19 +5,19 @@
5
5
  */
6
6
  /** Stable built-in relationship ontology without graph or storage dependencies. */
7
7
 
8
- !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]="825e1dd9-4168-56f6-9183-b8cf75314b73")}catch(e){}}();
8
+ !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]="aa7d04c7-b057-569c-816a-f53322c74261")}catch(e){}}();
9
9
  export const BUILTIN_RELATIONSHIP_KINDS = [
10
- { kind: "blocked_by", direction: "directed", inverse: "blocks", ordering: true, precedence: "target_before_source", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", aliases: ["depends_on"], compatibilityVersion: 1, allowSelf: false },
11
- { kind: "blocks", direction: "directed", inverse: "blocked_by", ordering: true, precedence: "source_before_target", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
12
- { kind: "parent", direction: "directed", inverse: "child", ordering: false, hierarchy: true, hierarchyDirection: "target_parent", outgoing: "one", incoming: "many", lifecycle: "supersedable", aliases: ["child_of", "epic"], compatibilityVersion: 1, allowSelf: false },
13
- { kind: "child", direction: "directed", inverse: "parent", ordering: false, hierarchy: true, hierarchyDirection: "source_parent", outgoing: "many", incoming: "one", lifecycle: "supersedable", aliases: ["parent_child", "task"], compatibilityVersion: 1, allowSelf: false },
14
- { kind: "related", direction: "undirected", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", aliases: ["related_to"], compatibilityVersion: 1, allowSelf: false },
15
- { kind: "discovered_from", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
16
- { kind: "incident_from", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
17
- { kind: "implements", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
18
- { kind: "recurs_from", direction: "directed", ordering: false, temporalOrder: "source_after_target", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
19
- { kind: "verifies", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
20
- { kind: "supersedes", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "supersedable", compatibilityVersion: 1, allowSelf: false },
10
+ { kind: "blocked_by", direction: "directed", traversal: "ordering", inverse: "blocks", ordering: true, precedence: "target_before_source", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", aliases: ["depends_on"], compatibilityVersion: 1, allowSelf: false },
11
+ { kind: "blocks", direction: "directed", traversal: "ordering", inverse: "blocked_by", ordering: true, precedence: "source_before_target", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
12
+ { kind: "parent", direction: "directed", traversal: "hierarchy", outcomeTraversal: "source_to_target", inverse: "child", ordering: false, hierarchy: true, hierarchyDirection: "target_parent", outgoing: "one", incoming: "many", lifecycle: "supersedable", aliases: ["child_of", "epic"], compatibilityVersion: 1, allowSelf: false },
13
+ { kind: "child", direction: "directed", traversal: "hierarchy", outcomeTraversal: "target_to_source", inverse: "parent", ordering: false, hierarchy: true, hierarchyDirection: "source_parent", outgoing: "many", incoming: "one", lifecycle: "supersedable", aliases: ["parent_child", "task"], compatibilityVersion: 1, allowSelf: false },
14
+ { kind: "related", direction: "undirected", traversal: "association", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", aliases: ["related_to"], compatibilityVersion: 1, allowSelf: false },
15
+ { kind: "discovered_from", direction: "directed", traversal: "semantic", outcomeTraversal: "source_to_target", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
16
+ { kind: "incident_from", direction: "directed", traversal: "semantic", outcomeTraversal: "source_to_target", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
17
+ { kind: "implements", direction: "directed", traversal: "semantic", outcomeTraversal: "source_to_target", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
18
+ { kind: "recurs_from", direction: "directed", traversal: "semantic", outcomeTraversal: "source_to_target", ordering: false, temporalOrder: "source_after_target", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
19
+ { kind: "verifies", direction: "directed", traversal: "semantic", outcomeTraversal: "source_to_target", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
20
+ { kind: "supersedes", direction: "directed", traversal: "semantic", outcomeTraversal: "both", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "supersedable", compatibilityVersion: 1, allowSelf: false },
21
21
  ];
22
22
  //# sourceMappingURL=contract.js.map
23
- //# debugId=825e1dd9-4168-56f6-9183-b8cf75314b73
23
+ //# debugId=aa7d04c7-b057-569c-816a-f53322c74261
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import type { Dependency, ItemMetadata } from "../types/index.js";
8
8
  import { type RelationshipKindDefinition } from "./relationship-kinds/contract.js";
9
- export { BUILTIN_RELATIONSHIP_KINDS, type RelationshipCardinality, type RelationshipDirection, type RelationshipHierarchyDirection, type RelationshipKindDefinition, type RelationshipLifecycle, type RelationshipPrecedence, type RelationshipTemporalOrder, } from "./relationship-kinds/contract.js";
9
+ export { BUILTIN_RELATIONSHIP_KINDS, type RelationshipCardinality, type RelationshipDirection, type RelationshipHierarchyDirection, type RelationshipKindDefinition, type RelationshipLifecycle, type RelationshipOutcomeTraversal, type RelationshipPrecedence, type RelationshipTemporalOrder, type RelationshipTraversalFamily, } from "./relationship-kinds/contract.js";
10
10
  /** One normalized relationship edge indexed by the graph kernel. */
11
11
  export interface RelationshipEdge {
12
12
  /** Source node identifier. */
@@ -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]="7f733de4-104b-50a9-9c0a-cd9850bfcd78")}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]="b1c32b57-0231-5bea-ade4-99247504f938")}catch(e){}}();
3
3
  import { BUILTIN_RELATIONSHIP_KINDS, } from "./relationship-kinds/contract.js";
4
4
  export { BUILTIN_RELATIONSHIP_KINDS, } from "./relationship-kinds/contract.js";
5
5
  function normalizeKind(kind) {
@@ -82,6 +82,16 @@ function assertRelationshipKindSemantics(definition, kind) {
82
82
  throw new TypeError(`Invalid relationship lifecycle for ${kind}`);
83
83
  if (typeof definition.allowSelf !== "boolean")
84
84
  throw new TypeError(`Invalid relationship self-edge flag for ${kind}`);
85
+ if (definition.traversal !== undefined &&
86
+ !["hierarchy", "ordering", "semantic", "association"].includes(definition.traversal))
87
+ throw new TypeError(`Invalid relationship traversal family for ${kind}`);
88
+ if (definition.outcomeTraversal !== undefined &&
89
+ !["source_to_target", "target_to_source", "both"].includes(definition.outcomeTraversal))
90
+ throw new TypeError(`Invalid outcome traversal for ${kind}`);
91
+ if (definition.direction === "undirected" &&
92
+ definition.outcomeTraversal !== undefined &&
93
+ definition.outcomeTraversal !== "both")
94
+ throw new TypeError(`Undirected relationship kind cannot declare directional outcome traversal: ${kind}`);
85
95
  }
86
96
  /** Validate application payload-schema and compatibility-alias containers. */
87
97
  function assertRelationshipKindPayload(definition, kind) {
@@ -129,6 +139,14 @@ export class RelationshipKindRegistry {
129
139
  const normalized = Object.freeze({
130
140
  ...definition,
131
141
  kind,
142
+ traversal: definition.traversal ??
143
+ (definition.hierarchy
144
+ ? "hierarchy"
145
+ : definition.ordering
146
+ ? "ordering"
147
+ : definition.direction === "undirected"
148
+ ? "association"
149
+ : "semantic"),
132
150
  hierarchy: definition.hierarchy ?? false,
133
151
  inverse,
134
152
  aliases: Object.freeze(aliases),
@@ -552,4 +570,4 @@ export function dependencyToRelationship(source, dependency, registry = defaultR
552
570
  };
553
571
  }
554
572
  //# sourceMappingURL=relationships.js.map
555
- //# debugId=7f733de4-104b-50a9-9c0a-cd9850bfcd78
573
+ //# debugId=b1c32b57-0231-5bea-ade4-99247504f938
@@ -72,7 +72,7 @@ export { splitCommaList } from "../core/shared/split-comma-list.js";
72
72
  export { compareTimestampStrings, nowIso, resolveIsoOrRelative, } from "../core/shared/time.js";
73
73
  export { migrateItemFilesToFormat } from "../core/store/item-format-migration.js";
74
74
  export { type CachedDocumentCandidate, listAllDocumentCandidatesCached, } from "../core/store/item-metadata-cache.js";
75
- export { buildItemNotFoundError, createMutationGuardSdk, deleteItem, listAllItemMetadata, listAllItemMetadataLight, locateItem, mutateItem, readLocatedItem, } from "../core/store/item-store.js";
75
+ export { buildItemNotFoundError, createMutationGuardSdk, deleteItem, listAllItemMetadata, listAllItemMetadataLight, locateItem, mutateItem, mutateItemWithHistoryContext, readLocatedItem, } from "../core/store/item-store.js";
76
76
  export { isTerminalPlanMode, shouldCompletePlanOnClose, } from "../core/item/plan-lifecycle.js";
77
77
  export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, } from "../core/store/paths.js";
78
78
  export { persistSelectedItemFormat, readSettings, readSettingsWithMetadata, writeSettings, } from "../core/store/settings.js";
@@ -7,7 +7,7 @@
7
7
  * prefer the typed operations exported by the main SDK barrel.
8
8
  */
9
9
 
10
- !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]="a678b9f8-ba36-5127-877f-96bb4acc38c5")}catch(e){}}();
10
+ !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]="1bcfba24-e761-571c-96e6-36bbc12d2814")}catch(e){}}();
11
11
  export { createCheckpointId, loadMutationCheckpoint, restoreCheckpointItems, writeMutationCheckpoint, } from "../core/checkpoint/mutation-checkpoint.js";
12
12
  export { flattenFlagListValue, resolveFlagValueKind, } from "../core/extensions/flag-value-types.js";
13
13
  export { createUnknownSubcommandError, } from "./agent/subcommand-recovery.js";
@@ -73,7 +73,7 @@ export { splitCommaList } from "../core/shared/split-comma-list.js";
73
73
  export { compareTimestampStrings, nowIso, resolveIsoOrRelative, } from "../core/shared/time.js";
74
74
  export { migrateItemFilesToFormat } from "../core/store/item-format-migration.js";
75
75
  export { listAllDocumentCandidatesCached, } from "../core/store/item-metadata-cache.js";
76
- export { buildItemNotFoundError, createMutationGuardSdk, deleteItem, listAllItemMetadata, listAllItemMetadataLight, locateItem, mutateItem, readLocatedItem, } from "../core/store/item-store.js";
76
+ export { buildItemNotFoundError, createMutationGuardSdk, deleteItem, listAllItemMetadata, listAllItemMetadataLight, locateItem, mutateItem, mutateItemWithHistoryContext, readLocatedItem, } from "../core/store/item-store.js";
77
77
  export { isTerminalPlanMode, shouldCompletePlanOnClose, } from "../core/item/plan-lifecycle.js";
78
78
  export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, } from "../core/store/paths.js";
79
79
  export { persistSelectedItemFormat, readSettings, readSettingsWithMetadata, writeSettings, } from "../core/store/settings.js";
@@ -81,4 +81,4 @@ export { maybeRunFirstUseTelemetryPrompt } from "../core/telemetry/consent.js";
81
81
  export { deriveTelemetryCommandResolution, } from "../core/telemetry/observability.js";
82
82
  export { emitTelemetryErrorEvent, finishTelemetryCommand, startTelemetryCommand, } from "../core/telemetry/runtime.js";
83
83
  //# sourceMappingURL=runtime-primitives.js.map
84
- //# debugId=a678b9f8-ba36-5127-877f-96bb4acc38c5
84
+ //# debugId=1bcfba24-e761-571c-96e6-36bbc12d2814
@@ -23,6 +23,7 @@ import { type AggregateOptions, type AggregateResult } from "./query/aggregate.j
23
23
  import { type UpgradeCommandOptions, type UpgradeResult } from "./governance/upgrade.js";
24
24
  import { type CreateResult } from "./lifecycle/create.js";
25
25
  import { type UpdateResult } from "./lifecycle/update.js";
26
+ import type { ReopenCommandOptions, ReopenResult } from "./lifecycle/reopen.js";
26
27
  import { type PlanCommandOptions, type PlanCommandResult, type PlanSubcommand } from "./lifecycle/plan.js";
27
28
  import { type ContextOptions, type ContextResult } from "./query/context.js";
28
29
  import { type NextOptions, type NextResult } from "./query/next.js";
@@ -93,6 +94,7 @@ export { runFocus, type FocusOptions, type FocusResult, } from "./lifecycle/focu
93
94
  export { runRestore, type RestoreCommandOptions, type RestoreResult, } from "./lifecycle/restore.js";
94
95
  export { DEFAULT_TERMINAL_TRANSITION_POLICY, applyTerminalOrderingPolicy, requireTerminalReason, resolveTerminalReason, type CloseOperationOptions, type CloseOperationResult, type TerminalOrderingMutation, type TerminalReasonInput, type TerminalReasonResolution, type TerminalReasonSource, type TerminalTransitionPolicy, } from "./lifecycle-policy.js";
95
96
  export { runUpdate, type UpdateCommandOptions } from "./lifecycle/update.js";
97
+ export { runReopen, type PreviousTerminalEvidence, type RecurrenceReceipt, type ReopenCommandOptions, type ReopenResult } from "./lifecycle/reopen.js";
96
98
  export { NEXT_OUTPUT_VALUES, runNext, type NextActionableItem, type NextBlockerRef, type NextOptions, type NextOutputFormat, type NextRecommendation, type NextResult, } from "./query/next.js";
97
99
  export { runSearch, type SearchCompactResult, type SearchHit, type SearchHitHighlight, type SearchMatchMode, type SearchOptions, type SearchResult, type SearchResultItem, type SearchVerboseResult, } from "./query/search.js";
98
100
  export { runStats, type StatsCommandOptions, type StatsResult, } from "./stats.js";
@@ -293,6 +295,8 @@ export declare class PmClient {
293
295
  create(options?: PmCreateActionOptions): Promise<CreateResult>;
294
296
  /** Update an item using the same mutation path as `pm update`. Options are contract-typed (pm-x29o): unknown keys and non-scalar values fail `tsc`; runtime-schema custom fields go through the repeatable `field` option, and {@link PmClient.run} stays the wide escape hatch. */
295
297
  update(id: string, options?: PmUpdateActionOptions): Promise<UpdateResult>;
298
+ /** Reopen terminal work as a recurrence through the canonical update path. */
299
+ reopen(id: string, reason: string, options?: ReopenCommandOptions): Promise<ReopenResult>;
296
300
  /** Close an item using the same mutation path as `pm close`. Options are contract-typed (pm-x29o); the close reason is the positional parameter, so the option bag omits `reason`/`text`. */
297
301
  close(id: string, reason: string, options?: PmClientCloseActionOptions): Promise<CloseResult>;
298
302
  /** Claim an item using the same mutation path as `pm claim`. */
@@ -469,6 +473,8 @@ export declare function historyCompactBulk(options: HistoryCompactBulkCommandOpt
469
473
  export declare function create(options?: PmCreateActionOptions, clientOptions?: PmClientOptions): Promise<CreateResult>;
470
474
  /** Update an item without constructing a reusable client. */
471
475
  export declare function update(id: string, options?: PmUpdateActionOptions, clientOptions?: PmClientOptions): Promise<UpdateResult>;
476
+ /** Reopen terminal work as a recurrence without constructing a reusable client. */
477
+ export declare function reopen(id: string, reason: string, options?: ReopenCommandOptions, clientOptions?: PmClientOptions): Promise<ReopenResult>;
472
478
  /** Close an item without constructing a reusable client. */
473
479
  export declare function close(id: string, reason: string, options?: PmClientCloseActionOptions, clientOptions?: PmClientOptions): Promise<CloseResult>;
474
480
  /** Claim an item without constructing a reusable client. */
@@ -4,7 +4,7 @@
4
4
  * Defines public SDK APIs and package-author helpers for Runtime.
5
5
  */
6
6
 
7
- !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]="95764dd9-1b0d-5732-9f10-b13b334ce27d")}catch(e){}}();
7
+ !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]="c770afea-3eb6-5476-ba07-8ec1c5d9c699")}catch(e){}}();
8
8
  export { PM_GITIGNORE_END, PM_GITIGNORE_START, ensurePmGitignore, getPmGitignoreBlock, } from "./workspace.js";
9
9
  export { SEARCH_EXTENSION_FLAG_DEFINITIONS } from "./extension-contracts.js";
10
10
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -70,6 +70,7 @@ import { acknowledgeUnknownAuthorHistoryEventsFromTransport, } from "./author-at
70
70
  import { PROFILE_SUBCOMMANDS, runProfileApply, runProfileLint, runProfileList, runProfileShow, } from "./profile.js";
71
71
  import { runHistoryRedact, } from "./history-redact.js";
72
72
  import { runMcpHistoryCompactAction, runMcpHistoryRepairAction, } from "./history-mcp.js";
73
+ import { runMcpCloseAction, runMcpReopenAction } from "./lifecycle/mcp-actions.js";
73
74
  import { actionGlobalOptions as globalOptions, closeManyOptionsFromFlat, extensionOptionsFromArgs, graphOptionsFromFlat, mutationListOptions, normalizeActionName, normalizeCommandPath, normalizeMcpOptionsArrays, normalizeMcpUpdateOptions, optionsWithAuthor, parseRuntimeInteger as parseMcpInteger, readRuntimeScalarString as readScalarString, readRuntimeScalarStringAllowBlank as readScalarStringAllowBlank, readRuntimeString as readString, readRuntimeStringArray as readStringArray, resolveRuntimeLimit, updateManyOptionsFromFlat, withAddNoteOption, withFilesDiscoveryOptions, withMutationCompaction, } from "./runtime-input.js";
74
75
  import { runDeps } from "./dependencies.js";
75
76
  import { runDocs } from "./docs.js";
@@ -119,6 +120,7 @@ export { runFocus, } from "./lifecycle/focus.js";
119
120
  export { runRestore, } from "./lifecycle/restore.js";
120
121
  export { DEFAULT_TERMINAL_TRANSITION_POLICY, applyTerminalOrderingPolicy, requireTerminalReason, resolveTerminalReason, } from "./lifecycle-policy.js";
121
122
  export { runUpdate } from "./lifecycle/update.js";
123
+ export { runReopen } from "./lifecycle/reopen.js";
122
124
  export { NEXT_OUTPUT_VALUES, runNext, } from "./query/next.js";
123
125
  export { runSearch, } from "./query/search.js";
124
126
  export { runStats, } from "./stats.js";
@@ -536,6 +538,15 @@ export class PmClient {
536
538
  ...splitFullClientMutationOptions(options),
537
539
  });
538
540
  }
541
+ /** Reopen terminal work as a recurrence through the canonical update path. */
542
+ reopen(id, reason, options = {}) {
543
+ return this.runTyped("item-reopen", {
544
+ id,
545
+ reason,
546
+ fullChangedFields: true,
547
+ options,
548
+ });
549
+ }
539
550
  /** Close an item using the same mutation path as `pm close`. Options are contract-typed (pm-x29o); the close reason is the positional parameter, so the option bag omits `reason`/`text`. */
540
551
  close(id, reason, options = {}) {
541
552
  return this.runTyped("close", {
@@ -908,6 +919,10 @@ export function create(options = {}, clientOptions = {}) {
908
919
  export function update(id, options = {}, clientOptions = {}) {
909
920
  return new PmClient(clientOptions).update(id, options);
910
921
  }
922
+ /** Reopen terminal work as a recurrence without constructing a reusable client. */
923
+ export function reopen(id, reason, options = {}, clientOptions = {}) {
924
+ return new PmClient(clientOptions).reopen(id, reason, options);
925
+ }
911
926
  /** Close an item without constructing a reusable client. */
912
927
  export function close(id, reason, options = {}, clientOptions = {}) {
913
928
  return new PmClient(clientOptions).close(id, reason, options);
@@ -1392,18 +1407,6 @@ async function runMcpUpdateAction(ctx) {
1392
1407
  idOnly,
1393
1408
  });
1394
1409
  }
1395
- async function runMcpCloseAction(ctx) {
1396
- const { changedFields, idOnly, runnerOptions } = withMutationCompaction(ctx.args, ctx.options);
1397
- const closeReason = readString(ctx.args, "reason") ??
1398
- readString(ctx.args, "text") ??
1399
- readString(runnerOptions, "reason") ??
1400
- readString(runnerOptions, "text");
1401
- return projectMutationResult(await runClose(requireMcpItemId(ctx, runnerOptions), closeReason, runnerOptions, ctx.global), {
1402
- changedFields,
1403
- compactEnvelope: changedFields === "compact" && !idOnly,
1404
- idOnly,
1405
- });
1406
- }
1407
1410
  function runMcpCommentsAction(ctx) {
1408
1411
  const commentOptions = normalizeAnnotationTransportOptions(ctx.options);
1409
1412
  const isListing = commentOptions.add === undefined &&
@@ -1808,6 +1811,7 @@ const SDK_ACTION_HANDLERS = {
1808
1811
  copy: runMcpCopyAction,
1809
1812
  focus: (ctx) => runFocus(ctx.id, { clear: ctx.options.clear === true || ctx.args.clear === true }, ctx.global),
1810
1813
  update: runMcpUpdateAction,
1814
+ "item-reopen": runMcpReopenAction,
1811
1815
  restore: runMcpRestoreAction,
1812
1816
  claim: (ctx) => ctx.options.next === true || ctx.args.next === true
1813
1817
  ? runClaimNext(ctx.force, ctx.global, { ...ctx.options, ...ctx.args }, { ...ctx.options, ...ctx.args })
@@ -1940,4 +1944,4 @@ async function loadWorkspaceExtensionRegistrations(pmRoot, settings, cwd) {
1940
1944
  }
1941
1945
  }
1942
1946
  //# sourceMappingURL=runtime.js.map
1943
- //# debugId=95764dd9-1b0d-5732-9f10-b13b334ce27d
1947
+ //# debugId=c770afea-3eb6-5476-ba07-8ec1c5d9c699
@@ -7,11 +7,12 @@
7
7
  * guarantees.
8
8
  */
9
9
 
10
- !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]="cd777de3-665f-5e01-ac98-8986f2a5a4c2")}catch(e){}}();
10
+ !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]="60738c1f-3b44-5f8a-82c9-99d2b2de1e51")}catch(e){}}();
11
+ import { assertInitializedTracker } from "./environment/tracker-preflight.js";
11
12
  import { createHash } from "node:crypto";
12
13
  import fs from "node:fs/promises";
13
14
  import path from "node:path";
14
- import { isFileMissingError, pathExists, readFileIfExists, writeFileAtomic, } from "../core/fs/fs-utils.js";
15
+ import { isFileMissingError, readFileIfExists, writeFileAtomic, } from "../core/fs/fs-utils.js";
15
16
  import { appendWorkspaceHistoryChange } from "../core/history/workspace-history.js";
16
17
  import { resolveItemTypeRegistry } from "../core/item/type-registry.js";
17
18
  import { parseFieldsFile, serializeFieldsFile, } from "../core/schema/fields-file.js";
@@ -21,7 +22,7 @@ import { parseStatusDefsFile, serializeStatusDefsFile, } from "../core/schema/st
21
22
  import { normalizeStatusToken } from "../core/schema/status-token.js";
22
23
  import { getActiveExtensionRegistrations } from "../core/extensions/index.js";
23
24
  import { listAllItemMetadataLight, locateItem, mutateItem, readLocatedItem, } from "../core/store/item-store.js";
24
- import { getSettingsPath, resolvePmRoot } from "../core/store/paths.js";
25
+ import { resolvePmRoot } from "../core/store/paths.js";
25
26
  import { readSettings } from "../core/store/settings.js";
26
27
  import { EXIT_CODE } from "../core/shared/constants.js";
27
28
  import { PmCliError } from "../core/shared/errors.js";
@@ -725,9 +726,7 @@ async function appendSchemaReferenceHistory(params) {
725
726
  export async function runSchemaEvolutionMigration(requestInput, options, global) {
726
727
  const request = normalizedRequest(requestInput);
727
728
  const pmRoot = resolvePmRoot(process.cwd(), global.path);
728
- if (!(await pathExists(getSettingsPath(pmRoot)))) {
729
- throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
730
- }
729
+ await assertInitializedTracker(pmRoot);
731
730
  const migrationId = options.migrationId === undefined
732
731
  ? deriveSchemaEvolutionMigrationId(request, await fs.realpath(pmRoot))
733
732
  : requiredMigrationId(options.migrationId);
@@ -855,4 +854,4 @@ export const schemaMigrationTestOnly = {
855
854
  validateAndStoreMigrationPlan,
856
855
  };
857
856
  //# sourceMappingURL=schema-migration.js.map
858
- //# debugId=cd777de3-665f-5e01-ac98-8986f2a5a4c2
857
+ //# debugId=60738c1f-3b44-5f8a-82c9-99d2b2de1e51