@unbrained/pm-cli 2026.5.1 → 2026.5.3-5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/AGENTS.md +8 -1
  2. package/CHANGELOG.md +73 -4
  3. package/CONTRIBUTING.md +11 -5
  4. package/PRD.md +17 -1
  5. package/README.md +55 -1099
  6. package/SECURITY.md +6 -11
  7. package/dist/cli/bootstrap-args.d.ts +18 -0
  8. package/dist/cli/bootstrap-args.js +242 -0
  9. package/dist/cli/bootstrap-args.js.map +1 -0
  10. package/dist/cli/commander-usage.d.ts +17 -0
  11. package/dist/cli/commander-usage.js +178 -0
  12. package/dist/cli/commander-usage.js.map +1 -0
  13. package/dist/cli/commands/activity.d.ts +10 -0
  14. package/dist/cli/commands/activity.js +14 -10
  15. package/dist/cli/commands/activity.js.map +1 -1
  16. package/dist/cli/commands/aggregate.js.map +1 -1
  17. package/dist/cli/commands/append.js.map +1 -1
  18. package/dist/cli/commands/calendar.js +19 -34
  19. package/dist/cli/commands/calendar.js.map +1 -1
  20. package/dist/cli/commands/claim.js.map +1 -1
  21. package/dist/cli/commands/close.js.map +1 -1
  22. package/dist/cli/commands/comments-audit.js.map +1 -1
  23. package/dist/cli/commands/comments.js +1 -9
  24. package/dist/cli/commands/comments.js.map +1 -1
  25. package/dist/cli/commands/completion.js.map +1 -1
  26. package/dist/cli/commands/config.d.ts +21 -3
  27. package/dist/cli/commands/config.js +118 -2
  28. package/dist/cli/commands/config.js.map +1 -1
  29. package/dist/cli/commands/context.d.ts +90 -1
  30. package/dist/cli/commands/context.js +496 -12
  31. package/dist/cli/commands/context.js.map +1 -1
  32. package/dist/cli/commands/contracts.js.map +1 -1
  33. package/dist/cli/commands/create.js +2 -2
  34. package/dist/cli/commands/create.js.map +1 -1
  35. package/dist/cli/commands/dedupe-audit.js +2 -11
  36. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  37. package/dist/cli/commands/delete.js.map +1 -1
  38. package/dist/cli/commands/deps.js.map +1 -1
  39. package/dist/cli/commands/docs.js.map +1 -1
  40. package/dist/cli/commands/extension.js.map +1 -1
  41. package/dist/cli/commands/files.js +14 -2
  42. package/dist/cli/commands/files.js.map +1 -1
  43. package/dist/cli/commands/gc.js.map +1 -1
  44. package/dist/cli/commands/get.js.map +1 -1
  45. package/dist/cli/commands/health.js +16 -12
  46. package/dist/cli/commands/health.js.map +1 -1
  47. package/dist/cli/commands/history.js +1 -9
  48. package/dist/cli/commands/history.js.map +1 -1
  49. package/dist/cli/commands/index.js.map +1 -1
  50. package/dist/cli/commands/init.js.map +1 -1
  51. package/dist/cli/commands/learnings.js +1 -9
  52. package/dist/cli/commands/learnings.js.map +1 -1
  53. package/dist/cli/commands/list.d.ts +1 -0
  54. package/dist/cli/commands/list.js +13 -31
  55. package/dist/cli/commands/list.js.map +1 -1
  56. package/dist/cli/commands/normalize.js +14 -23
  57. package/dist/cli/commands/normalize.js.map +1 -1
  58. package/dist/cli/commands/notes.js +1 -9
  59. package/dist/cli/commands/notes.js.map +1 -1
  60. package/dist/cli/commands/reindex.js +2 -7
  61. package/dist/cli/commands/reindex.js.map +1 -1
  62. package/dist/cli/commands/restore.js.map +1 -1
  63. package/dist/cli/commands/search.js +4 -35
  64. package/dist/cli/commands/search.js.map +1 -1
  65. package/dist/cli/commands/stats.js.map +1 -1
  66. package/dist/cli/commands/templates.js.map +1 -1
  67. package/dist/cli/commands/test-all.js.map +1 -1
  68. package/dist/cli/commands/test-runs.js +1 -11
  69. package/dist/cli/commands/test-runs.js.map +1 -1
  70. package/dist/cli/commands/test.js.map +1 -1
  71. package/dist/cli/commands/update-many.js +1 -6
  72. package/dist/cli/commands/update-many.js.map +1 -1
  73. package/dist/cli/commands/update.js +2 -2
  74. package/dist/cli/commands/update.js.map +1 -1
  75. package/dist/cli/commands/validate.js +23 -18
  76. package/dist/cli/commands/validate.js.map +1 -1
  77. package/dist/cli/error-guidance.d.ts +13 -0
  78. package/dist/cli/error-guidance.js +56 -6
  79. package/dist/cli/error-guidance.js.map +1 -1
  80. package/dist/cli/extension-command-help.d.ts +48 -0
  81. package/dist/cli/extension-command-help.js +389 -0
  82. package/dist/cli/extension-command-help.js.map +1 -0
  83. package/dist/cli/extension-command-options.js.map +1 -1
  84. package/dist/cli/help-content.js +9 -3
  85. package/dist/cli/help-content.js.map +1 -1
  86. package/dist/cli/help-json-payload.d.ts +25 -0
  87. package/dist/cli/help-json-payload.js +265 -0
  88. package/dist/cli/help-json-payload.js.map +1 -0
  89. package/dist/cli/main.js +1000 -4456
  90. package/dist/cli/main.js.map +1 -1
  91. package/dist/cli/migration-gates.d.ts +22 -0
  92. package/dist/cli/migration-gates.js +146 -0
  93. package/dist/cli/migration-gates.js.map +1 -0
  94. package/dist/cli/register-list-query.d.ts +2 -0
  95. package/dist/cli/register-list-query.js +317 -0
  96. package/dist/cli/register-list-query.js.map +1 -0
  97. package/dist/cli/register-mutation.d.ts +2 -0
  98. package/dist/cli/register-mutation.js +795 -0
  99. package/dist/cli/register-mutation.js.map +1 -0
  100. package/dist/cli/register-operations.d.ts +2 -0
  101. package/dist/cli/register-operations.js +610 -0
  102. package/dist/cli/register-operations.js.map +1 -0
  103. package/dist/cli/register-setup.d.ts +2 -0
  104. package/dist/cli/register-setup.js +334 -0
  105. package/dist/cli/register-setup.js.map +1 -0
  106. package/dist/cli/registration-helpers.d.ts +53 -0
  107. package/dist/cli/registration-helpers.js +669 -0
  108. package/dist/cli/registration-helpers.js.map +1 -0
  109. package/dist/cli/shared-parsers.d.ts +6 -0
  110. package/dist/cli/shared-parsers.js +40 -0
  111. package/dist/cli/shared-parsers.js.map +1 -0
  112. package/dist/cli.d.ts +1 -1
  113. package/dist/cli.js +3 -1
  114. package/dist/cli.js.map +1 -1
  115. package/dist/core/extensions/extension-types.d.ts +605 -0
  116. package/dist/core/extensions/extension-types.js +22 -0
  117. package/dist/core/extensions/extension-types.js.map +1 -0
  118. package/dist/core/extensions/index.js.map +1 -1
  119. package/dist/core/extensions/item-fields.js.map +1 -1
  120. package/dist/core/extensions/loader.d.ts +2 -586
  121. package/dist/core/extensions/loader.js +3 -21
  122. package/dist/core/extensions/loader.js.map +1 -1
  123. package/dist/core/extensions/runtime-registrations.js.map +1 -1
  124. package/dist/core/fs/fs-utils.js.map +1 -1
  125. package/dist/core/fs/index.js.map +1 -1
  126. package/dist/core/history/history-stream-policy.js.map +1 -1
  127. package/dist/core/history/history.js.map +1 -1
  128. package/dist/core/history/index.js.map +1 -1
  129. package/dist/core/item/id.js.map +1 -1
  130. package/dist/core/item/index.js.map +1 -1
  131. package/dist/core/item/item-format.js.map +1 -1
  132. package/dist/core/item/parent-reference-policy.js.map +1 -1
  133. package/dist/core/item/parse.js +6 -0
  134. package/dist/core/item/parse.js.map +1 -1
  135. package/dist/core/item/sprint-release-format.js.map +1 -1
  136. package/dist/core/item/status.js.map +1 -1
  137. package/dist/core/item/type-registry.js.map +1 -1
  138. package/dist/core/lock/index.js.map +1 -1
  139. package/dist/core/lock/lock.js +1 -6
  140. package/dist/core/lock/lock.js.map +1 -1
  141. package/dist/core/output/command-aware.js.map +1 -1
  142. package/dist/core/output/output.js.map +1 -1
  143. package/dist/core/schema/runtime-field-filters.js.map +1 -1
  144. package/dist/core/schema/runtime-field-values.js.map +1 -1
  145. package/dist/core/schema/runtime-schema.js.map +1 -1
  146. package/dist/core/search/cache.js +1 -7
  147. package/dist/core/search/cache.js.map +1 -1
  148. package/dist/core/search/embedding-batches.js +4 -0
  149. package/dist/core/search/embedding-batches.js.map +1 -1
  150. package/dist/core/search/http-client.d.ts +29 -0
  151. package/dist/core/search/http-client.js +64 -0
  152. package/dist/core/search/http-client.js.map +1 -0
  153. package/dist/core/search/providers.d.ts +3 -13
  154. package/dist/core/search/providers.js +19 -88
  155. package/dist/core/search/providers.js.map +1 -1
  156. package/dist/core/search/semantic-defaults.js +2 -7
  157. package/dist/core/search/semantic-defaults.js.map +1 -1
  158. package/dist/core/search/vector-stores.d.ts +4 -13
  159. package/dist/core/search/vector-stores.js +40 -93
  160. package/dist/core/search/vector-stores.js.map +1 -1
  161. package/dist/core/sentry/helpers.d.ts +27 -0
  162. package/dist/core/sentry/helpers.js +171 -0
  163. package/dist/core/sentry/helpers.js.map +1 -0
  164. package/dist/core/sentry/instrument.d.ts +25 -0
  165. package/dist/core/sentry/instrument.js +204 -0
  166. package/dist/core/sentry/instrument.js.map +1 -0
  167. package/dist/core/shared/command-types.js.map +1 -1
  168. package/dist/core/shared/conflict-markers.js.map +1 -1
  169. package/dist/core/shared/constants.d.ts +3 -0
  170. package/dist/core/shared/constants.js +58 -1
  171. package/dist/core/shared/constants.js.map +1 -1
  172. package/dist/core/shared/errors.js.map +1 -1
  173. package/dist/core/shared/index.d.ts +1 -0
  174. package/dist/core/shared/index.js +1 -0
  175. package/dist/core/shared/index.js.map +1 -1
  176. package/dist/core/shared/primitives.d.ts +13 -0
  177. package/dist/core/shared/primitives.js +33 -0
  178. package/dist/core/shared/primitives.js.map +1 -0
  179. package/dist/core/shared/serialization.js.map +1 -1
  180. package/dist/core/shared/text-normalization.js.map +1 -1
  181. package/dist/core/shared/time.js.map +1 -1
  182. package/dist/core/store/front-matter-cache.d.ts +6 -0
  183. package/dist/core/store/front-matter-cache.js +150 -0
  184. package/dist/core/store/front-matter-cache.js.map +1 -0
  185. package/dist/core/store/index.js.map +1 -1
  186. package/dist/core/store/item-format-migration.js.map +1 -1
  187. package/dist/core/store/item-store.js +46 -36
  188. package/dist/core/store/item-store.js.map +1 -1
  189. package/dist/core/store/paths.js.map +1 -1
  190. package/dist/core/store/settings.js +36 -0
  191. package/dist/core/store/settings.js.map +1 -1
  192. package/dist/core/telemetry/consent.js.map +1 -1
  193. package/dist/core/telemetry/observability.d.ts +24 -0
  194. package/dist/core/telemetry/observability.js +185 -0
  195. package/dist/core/telemetry/observability.js.map +1 -0
  196. package/dist/core/telemetry/runtime.d.ts +29 -3
  197. package/dist/core/telemetry/runtime.js +337 -25
  198. package/dist/core/telemetry/runtime.js.map +1 -1
  199. package/dist/core/test/background-runs.js.map +1 -1
  200. package/dist/core/test/item-test-run-tracking.js.map +1 -1
  201. package/dist/sdk/cli-contracts.js +28 -0
  202. package/dist/sdk/cli-contracts.js.map +1 -1
  203. package/dist/sdk/index.d.ts +1 -1
  204. package/dist/sdk/index.js.map +1 -1
  205. package/dist/types/index.js.map +1 -1
  206. package/dist/types.d.ts +21 -0
  207. package/dist/types.js +11 -0
  208. package/dist/types.js.map +1 -1
  209. package/docs/AGENT_GUIDE.md +125 -0
  210. package/docs/ARCHITECTURE.md +201 -478
  211. package/docs/COMMANDS.md +209 -0
  212. package/docs/CONFIGURATION.md +146 -0
  213. package/docs/EXTENSIONS.md +146 -645
  214. package/docs/QUICKSTART.md +108 -0
  215. package/docs/README.md +70 -0
  216. package/docs/RELEASING.md +92 -50
  217. package/docs/SDK.md +127 -68
  218. package/docs/TESTING.md +125 -0
  219. package/docs/examples/starter-extension/README.md +39 -25
  220. package/package.json +24 -11
  221. package/dist/command-types.d.ts +0 -1
  222. package/dist/command-types.js +0 -2
  223. package/dist/command-types.js.map +0 -1
  224. package/dist/constants.d.ts +0 -1
  225. package/dist/constants.js +0 -2
  226. package/dist/constants.js.map +0 -1
  227. package/dist/errors.d.ts +0 -1
  228. package/dist/errors.js +0 -2
  229. package/dist/errors.js.map +0 -1
  230. package/dist/fs-utils.d.ts +0 -1
  231. package/dist/fs-utils.js +0 -2
  232. package/dist/fs-utils.js.map +0 -1
  233. package/dist/history.d.ts +0 -1
  234. package/dist/history.js +0 -2
  235. package/dist/history.js.map +0 -1
  236. package/dist/id.d.ts +0 -1
  237. package/dist/id.js +0 -2
  238. package/dist/id.js.map +0 -1
  239. package/dist/item-format.d.ts +0 -1
  240. package/dist/item-format.js +0 -2
  241. package/dist/item-format.js.map +0 -1
  242. package/dist/item-store.d.ts +0 -1
  243. package/dist/item-store.js +0 -2
  244. package/dist/item-store.js.map +0 -1
  245. package/dist/lock.d.ts +0 -1
  246. package/dist/lock.js +0 -2
  247. package/dist/lock.js.map +0 -1
  248. package/dist/output.d.ts +0 -1
  249. package/dist/output.js +0 -2
  250. package/dist/output.js.map +0 -1
  251. package/dist/parse.d.ts +0 -1
  252. package/dist/parse.js +0 -2
  253. package/dist/parse.js.map +0 -1
  254. package/dist/paths.d.ts +0 -1
  255. package/dist/paths.js +0 -2
  256. package/dist/paths.js.map +0 -1
  257. package/dist/serialization.d.ts +0 -1
  258. package/dist/serialization.js +0 -2
  259. package/dist/serialization.js.map +0 -1
  260. package/dist/settings.d.ts +0 -1
  261. package/dist/settings.js +0 -2
  262. package/dist/settings.js.map +0 -1
  263. package/dist/time.d.ts +0 -1
  264. package/dist/time.js +0 -2
  265. package/dist/time.js.map +0 -1
@@ -0,0 +1,669 @@
1
+ import { pathExists } from "../core/fs/fs-utils.js";
2
+ import { refreshSearchArtifactsForMutation } from "../core/search/cache.js";
3
+ import { EXIT_CODE } from "../core/shared/constants.js";
4
+ import { PmCliError } from "../core/shared/errors.js";
5
+ import { printError, printResult, writeStdout } from "../core/output/output.js";
6
+ import { getSettingsPath, resolvePmRoot } from "../core/store/paths.js";
7
+ import { readSettings } from "../core/store/settings.js";
8
+ import { setActiveCommandResult, } from "../core/extensions/index.js";
9
+ import { ACTIVITY_COMMANDER_STRING_OPTION_CONTRACTS, CALENDAR_COMMANDER_STRING_OPTION_CONTRACTS, CONTEXT_COMMANDER_STRING_OPTION_CONTRACTS, CREATE_COMMANDER_REPEATABLE_OPTION_CONTRACTS, CREATE_COMMANDER_STRING_OPTION_CONTRACTS, LIST_COMMANDER_STRING_OPTION_CONTRACTS, SEARCH_COMMANDER_STRING_OPTION_CONTRACTS, UPDATE_COMMANDER_REPEATABLE_OPTION_CONTRACTS, UPDATE_COMMANDER_STRING_OPTION_CONTRACTS, readFirstStringFromCommanderOptions, readStringArrayFromCommanderOptions, } from "../sdk/cli-contracts.js";
10
+ export { printError, printResult, writeStdout, };
11
+ const RESOLVED_GLOBAL_OPTIONS = Symbol("pm.resolvedGlobalOptions");
12
+ export function setResolvedGlobalOptions(command, globalOptions) {
13
+ command[RESOLVED_GLOBAL_OPTIONS] = { ...globalOptions };
14
+ }
15
+ export function clearResolvedGlobalOptions(command) {
16
+ delete command[RESOLVED_GLOBAL_OPTIONS];
17
+ }
18
+ export function getGlobalOptions(command) {
19
+ const resolved = command[RESOLVED_GLOBAL_OPTIONS];
20
+ if (resolved) {
21
+ return { ...resolved };
22
+ }
23
+ const opts = command.optsWithGlobals();
24
+ return {
25
+ json: opts.json === true ? true : undefined,
26
+ quiet: Boolean(opts.quiet),
27
+ path: typeof opts.path === "string" ? opts.path : undefined,
28
+ noExtensions: opts.extensions === false,
29
+ noPager: Boolean(opts.noPager),
30
+ profile: Boolean(opts.profile),
31
+ };
32
+ }
33
+ export function getCommandPath(command) {
34
+ const parts = [];
35
+ let current = command;
36
+ while (current?.parent) {
37
+ parts.unshift(current.name());
38
+ current = current.parent;
39
+ }
40
+ return parts.join(" ");
41
+ }
42
+ export async function applyDefaultOutputFormat(globalOptions) {
43
+ if (globalOptions.json === true) {
44
+ return globalOptions;
45
+ }
46
+ const pmRoot = resolvePmRoot(process.cwd(), globalOptions.path);
47
+ if (!(await pathExists(getSettingsPath(pmRoot)))) {
48
+ return globalOptions;
49
+ }
50
+ const settings = await readSettings(pmRoot);
51
+ return {
52
+ ...globalOptions,
53
+ defaultOutputFormat: settings.output.default_format,
54
+ };
55
+ }
56
+ export function collect(value, previous) {
57
+ const next = previous ?? [];
58
+ next.push(value);
59
+ return next;
60
+ }
61
+ export function pushOptionalValueFlag(args, flag, value) {
62
+ if (typeof value !== "string") {
63
+ return;
64
+ }
65
+ const trimmed = value.trim();
66
+ if (trimmed.length === 0) {
67
+ return;
68
+ }
69
+ args.push(flag, trimmed);
70
+ }
71
+ export function pushOptionalBooleanFlag(args, flag, value) {
72
+ if (value === true) {
73
+ args.push(flag);
74
+ }
75
+ }
76
+ export function pushRepeatableValueFlag(args, flag, values) {
77
+ if (!Array.isArray(values)) {
78
+ return;
79
+ }
80
+ for (const value of values) {
81
+ if (typeof value !== "string") {
82
+ continue;
83
+ }
84
+ const trimmed = value.trim();
85
+ if (trimmed.length === 0) {
86
+ continue;
87
+ }
88
+ args.push(flag, trimmed);
89
+ }
90
+ }
91
+ export function buildBackgroundTestCommandArgs(id, options) {
92
+ const args = ["test", id, "--run", "--json", "--progress"];
93
+ pushRepeatableValueFlag(args, "--add", options.add);
94
+ pushRepeatableValueFlag(args, "--remove", options.remove);
95
+ pushOptionalValueFlag(args, "--timeout", options.timeout);
96
+ pushRepeatableValueFlag(args, "--env-set", options.envSet);
97
+ pushRepeatableValueFlag(args, "--env-clear", options.envClear);
98
+ pushOptionalBooleanFlag(args, "--shared-host-safe", options.sharedHostSafe);
99
+ pushOptionalValueFlag(args, "--pm-context", options.pmContext);
100
+ pushOptionalBooleanFlag(args, "--override-linked-pm-context", options.overrideLinkedPmContext);
101
+ pushOptionalBooleanFlag(args, "--fail-on-context-mismatch", options.failOnContextMismatch);
102
+ pushOptionalBooleanFlag(args, "--fail-on-skipped", options.failOnSkipped);
103
+ pushOptionalBooleanFlag(args, "--fail-on-empty-test-run", options.failOnEmptyTestRun);
104
+ pushOptionalBooleanFlag(args, "--require-assertions-for-pm", options.requireAssertionsForPm);
105
+ pushOptionalBooleanFlag(args, "--check-context", options.checkContext);
106
+ pushOptionalBooleanFlag(args, "--auto-pm-context", options.autoPmContext);
107
+ pushOptionalValueFlag(args, "--author", options.author);
108
+ pushOptionalValueFlag(args, "--message", options.message);
109
+ pushOptionalBooleanFlag(args, "--force", options.force);
110
+ return args;
111
+ }
112
+ export function buildBackgroundTestAllCommandArgs(options) {
113
+ const args = ["test-all", "--json", "--progress"];
114
+ pushOptionalValueFlag(args, "--status", options.status);
115
+ pushOptionalValueFlag(args, "--limit", options.limit);
116
+ pushOptionalValueFlag(args, "--offset", options.offset);
117
+ pushOptionalValueFlag(args, "--timeout", options.timeout);
118
+ pushRepeatableValueFlag(args, "--env-set", options.envSet);
119
+ pushRepeatableValueFlag(args, "--env-clear", options.envClear);
120
+ pushOptionalBooleanFlag(args, "--shared-host-safe", options.sharedHostSafe);
121
+ pushOptionalValueFlag(args, "--pm-context", options.pmContext);
122
+ pushOptionalBooleanFlag(args, "--override-linked-pm-context", options.overrideLinkedPmContext);
123
+ pushOptionalBooleanFlag(args, "--fail-on-context-mismatch", options.failOnContextMismatch);
124
+ pushOptionalBooleanFlag(args, "--fail-on-skipped", options.failOnSkipped);
125
+ pushOptionalBooleanFlag(args, "--fail-on-empty-test-run", options.failOnEmptyTestRun);
126
+ pushOptionalBooleanFlag(args, "--require-assertions-for-pm", options.requireAssertionsForPm);
127
+ pushOptionalBooleanFlag(args, "--check-context", options.checkContext);
128
+ pushOptionalBooleanFlag(args, "--auto-pm-context", options.autoPmContext);
129
+ return args;
130
+ }
131
+ export function formatHookWarnings(warnings) {
132
+ return warnings.join(",");
133
+ }
134
+ export function normalizeCreateOptions(commandOptions, options = {}) {
135
+ const readCreateString = (target) => readFirstStringFromCommanderOptions(commandOptions, CREATE_COMMANDER_STRING_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
136
+ target,
137
+ keys: [target],
138
+ });
139
+ const readCreateList = (target) => readStringArrayFromCommanderOptions(commandOptions, CREATE_COMMANDER_REPEATABLE_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
140
+ target,
141
+ keys: [target],
142
+ });
143
+ const type = readCreateString("type");
144
+ if (options.requireType !== false && type === undefined) {
145
+ throw new PmCliError("Missing required option --type <value>", EXIT_CODE.USAGE);
146
+ }
147
+ const normalized = {
148
+ title: readCreateString("title"),
149
+ description: readCreateString("description"),
150
+ type,
151
+ template: readCreateString("template"),
152
+ createMode: readCreateString("createMode"),
153
+ schedulePreset: readCreateString("schedulePreset"),
154
+ status: readCreateString("status"),
155
+ priority: readCreateString("priority"),
156
+ tags: readCreateString("tags"),
157
+ body: readCreateString("body"),
158
+ deadline: readCreateString("deadline"),
159
+ estimatedMinutes: readCreateString("estimatedMinutes"),
160
+ acceptanceCriteria: readCreateString("acceptanceCriteria"),
161
+ definitionOfReady: readCreateString("definitionOfReady"),
162
+ order: readCreateString("order"),
163
+ rank: readCreateString("rank"),
164
+ goal: readCreateString("goal"),
165
+ objective: readCreateString("objective"),
166
+ value: readCreateString("value"),
167
+ impact: readCreateString("impact"),
168
+ outcome: readCreateString("outcome"),
169
+ whyNow: readCreateString("whyNow"),
170
+ author: readCreateString("author"),
171
+ message: readCreateString("message"),
172
+ assignee: readCreateString("assignee"),
173
+ parent: readCreateString("parent"),
174
+ reviewer: readCreateString("reviewer"),
175
+ risk: readCreateString("risk"),
176
+ confidence: readCreateString("confidence"),
177
+ sprint: readCreateString("sprint"),
178
+ release: readCreateString("release"),
179
+ blockedBy: readCreateString("blockedBy"),
180
+ blockedReason: readCreateString("blockedReason"),
181
+ unblockNote: readCreateString("unblockNote"),
182
+ reporter: readCreateString("reporter"),
183
+ severity: readCreateString("severity"),
184
+ environment: readCreateString("environment"),
185
+ reproSteps: readCreateString("reproSteps"),
186
+ resolution: readCreateString("resolution"),
187
+ expectedResult: readCreateString("expectedResult"),
188
+ actualResult: readCreateString("actualResult"),
189
+ affectedVersion: readCreateString("affectedVersion"),
190
+ fixedVersion: readCreateString("fixedVersion"),
191
+ component: readCreateString("component"),
192
+ regression: readCreateString("regression"),
193
+ customerImpact: readCreateString("customerImpact"),
194
+ dep: readCreateList("dep"),
195
+ comment: readCreateList("comment"),
196
+ note: readCreateList("note"),
197
+ learning: readCreateList("learning"),
198
+ file: readCreateList("file"),
199
+ test: readCreateList("test"),
200
+ doc: readCreateList("doc"),
201
+ reminder: readCreateList("reminder"),
202
+ event: readCreateList("event"),
203
+ typeOption: readCreateList("typeOption"),
204
+ unset: readCreateList("unset"),
205
+ clearDeps: commandOptions.clearDeps === true ? true : undefined,
206
+ clearComments: commandOptions.clearComments === true ? true : undefined,
207
+ clearNotes: commandOptions.clearNotes === true ? true : undefined,
208
+ clearLearnings: commandOptions.clearLearnings === true ? true : undefined,
209
+ clearFiles: commandOptions.clearFiles === true ? true : undefined,
210
+ clearTests: commandOptions.clearTests === true ? true : undefined,
211
+ clearDocs: commandOptions.clearDocs === true ? true : undefined,
212
+ clearReminders: commandOptions.clearReminders === true ? true : undefined,
213
+ clearEvents: commandOptions.clearEvents === true ? true : undefined,
214
+ clearTypeOptions: commandOptions.clearTypeOptions === true ? true : undefined,
215
+ };
216
+ for (const [key, value] of Object.entries(commandOptions)) {
217
+ if (Object.hasOwn(normalized, key)) {
218
+ continue;
219
+ }
220
+ normalized[key] = value;
221
+ }
222
+ return normalized;
223
+ }
224
+ export function normalizeUpdateOptions(commandOptions) {
225
+ const readUpdateString = (target) => readFirstStringFromCommanderOptions(commandOptions, UPDATE_COMMANDER_STRING_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
226
+ target,
227
+ keys: [target],
228
+ });
229
+ const readUpdateList = (target) => readStringArrayFromCommanderOptions(commandOptions, UPDATE_COMMANDER_REPEATABLE_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
230
+ target,
231
+ keys: [target],
232
+ });
233
+ const normalized = {
234
+ title: readUpdateString("title"),
235
+ description: readUpdateString("description"),
236
+ body: readUpdateString("body"),
237
+ status: readUpdateString("status"),
238
+ closeReason: readUpdateString("closeReason"),
239
+ priority: readUpdateString("priority"),
240
+ type: readUpdateString("type"),
241
+ tags: readUpdateString("tags"),
242
+ deadline: readUpdateString("deadline"),
243
+ estimatedMinutes: readUpdateString("estimatedMinutes"),
244
+ acceptanceCriteria: readUpdateString("acceptanceCriteria"),
245
+ definitionOfReady: readUpdateString("definitionOfReady"),
246
+ order: readUpdateString("order"),
247
+ rank: readUpdateString("rank"),
248
+ goal: readUpdateString("goal"),
249
+ objective: readUpdateString("objective"),
250
+ value: readUpdateString("value"),
251
+ impact: readUpdateString("impact"),
252
+ outcome: readUpdateString("outcome"),
253
+ whyNow: readUpdateString("whyNow"),
254
+ author: readUpdateString("author"),
255
+ message: readUpdateString("message"),
256
+ force: Boolean(commandOptions.force),
257
+ allowAuditUpdate: commandOptions.allowAuditUpdate === true || commandOptions.allow_audit_update === true ? true : undefined,
258
+ allowAuditDepUpdate: commandOptions.allowAuditDepUpdate === true || commandOptions.allow_audit_dep_update === true ? true : undefined,
259
+ assignee: readUpdateString("assignee"),
260
+ parent: readUpdateString("parent"),
261
+ reviewer: readUpdateString("reviewer"),
262
+ risk: readUpdateString("risk"),
263
+ confidence: readUpdateString("confidence"),
264
+ sprint: readUpdateString("sprint"),
265
+ release: readUpdateString("release"),
266
+ blockedBy: readUpdateString("blockedBy"),
267
+ blockedReason: readUpdateString("blockedReason"),
268
+ unblockNote: readUpdateString("unblockNote"),
269
+ reporter: readUpdateString("reporter"),
270
+ severity: readUpdateString("severity"),
271
+ environment: readUpdateString("environment"),
272
+ reproSteps: readUpdateString("reproSteps"),
273
+ resolution: readUpdateString("resolution"),
274
+ expectedResult: readUpdateString("expectedResult"),
275
+ actualResult: readUpdateString("actualResult"),
276
+ affectedVersion: readUpdateString("affectedVersion"),
277
+ fixedVersion: readUpdateString("fixedVersion"),
278
+ component: readUpdateString("component"),
279
+ regression: readUpdateString("regression"),
280
+ customerImpact: readUpdateString("customerImpact"),
281
+ dep: readUpdateList("dep"),
282
+ depRemove: readUpdateList("depRemove"),
283
+ replaceDeps: commandOptions.replaceDeps === true ? true : undefined,
284
+ replaceTests: commandOptions.replaceTests === true ? true : undefined,
285
+ comment: readUpdateList("comment"),
286
+ note: readUpdateList("note"),
287
+ learning: readUpdateList("learning"),
288
+ file: readUpdateList("file"),
289
+ test: readUpdateList("test"),
290
+ doc: readUpdateList("doc"),
291
+ reminder: readUpdateList("reminder"),
292
+ event: readUpdateList("event"),
293
+ typeOption: readUpdateList("typeOption"),
294
+ unset: readUpdateList("unset"),
295
+ clearDeps: commandOptions.clearDeps === true ? true : undefined,
296
+ clearComments: commandOptions.clearComments === true ? true : undefined,
297
+ clearNotes: commandOptions.clearNotes === true ? true : undefined,
298
+ clearLearnings: commandOptions.clearLearnings === true ? true : undefined,
299
+ clearFiles: commandOptions.clearFiles === true ? true : undefined,
300
+ clearTests: commandOptions.clearTests === true ? true : undefined,
301
+ clearDocs: commandOptions.clearDocs === true ? true : undefined,
302
+ clearReminders: commandOptions.clearReminders === true ? true : undefined,
303
+ clearEvents: commandOptions.clearEvents === true ? true : undefined,
304
+ clearTypeOptions: commandOptions.clearTypeOptions === true ? true : undefined,
305
+ };
306
+ for (const [key, value] of Object.entries(commandOptions)) {
307
+ if (Object.hasOwn(normalized, key)) {
308
+ continue;
309
+ }
310
+ normalized[key] = value;
311
+ }
312
+ return normalized;
313
+ }
314
+ export const UPDATE_MANY_CONTROL_OPTION_KEYS = new Set([
315
+ "filterStatus",
316
+ "filterType",
317
+ "filterTag",
318
+ "filterPriority",
319
+ "filterDeadlineBefore",
320
+ "filterDeadlineAfter",
321
+ "filterAssignee",
322
+ "filterAssigneeFilter",
323
+ "filterAssignee_filter",
324
+ "filterParent",
325
+ "filterSprint",
326
+ "filterRelease",
327
+ "limit",
328
+ "offset",
329
+ "dryRun",
330
+ "rollback",
331
+ "checkpoint",
332
+ ]);
333
+ export function extractUpdateManyMutationOptionSource(commandOptions) {
334
+ const mutationOptions = {};
335
+ for (const [key, value] of Object.entries(commandOptions)) {
336
+ if (UPDATE_MANY_CONTROL_OPTION_KEYS.has(key)) {
337
+ continue;
338
+ }
339
+ mutationOptions[key] = value;
340
+ }
341
+ return mutationOptions;
342
+ }
343
+ function readListOptionString(options, target) {
344
+ return readFirstStringFromCommanderOptions(options, LIST_COMMANDER_STRING_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
345
+ target,
346
+ keys: [target],
347
+ });
348
+ }
349
+ export function normalizeListOptions(options) {
350
+ const normalized = {
351
+ status: readListOptionString(options, "status"),
352
+ type: readListOptionString(options, "type"),
353
+ tag: readListOptionString(options, "tag"),
354
+ priority: readListOptionString(options, "priority"),
355
+ deadlineBefore: readListOptionString(options, "deadlineBefore"),
356
+ deadlineAfter: readListOptionString(options, "deadlineAfter"),
357
+ assignee: readListOptionString(options, "assignee"),
358
+ assigneeFilter: readListOptionString(options, "assigneeFilter"),
359
+ parent: readListOptionString(options, "parent"),
360
+ sprint: readListOptionString(options, "sprint"),
361
+ release: readListOptionString(options, "release"),
362
+ limit: readListOptionString(options, "limit"),
363
+ offset: readListOptionString(options, "offset"),
364
+ includeBody: options.includeBody === true ? true : undefined,
365
+ compact: options.compact === true ? true : undefined,
366
+ fields: readListOptionString(options, "fields"),
367
+ sort: readListOptionString(options, "sort"),
368
+ order: readListOptionString(options, "order"),
369
+ };
370
+ for (const [key, value] of Object.entries(options)) {
371
+ if (Object.hasOwn(normalized, key)) {
372
+ continue;
373
+ }
374
+ normalized[key] = value;
375
+ }
376
+ return normalized;
377
+ }
378
+ export function normalizeAggregateOptions(options) {
379
+ return {
380
+ groupBy: typeof options.groupBy === "string" ? options.groupBy : undefined,
381
+ count: options.count === true ? true : undefined,
382
+ includeUnparented: options.includeUnparented === true || options.include_unparented === true,
383
+ status: typeof options.status === "string" ? options.status : undefined,
384
+ type: readListOptionString(options, "type"),
385
+ tag: readListOptionString(options, "tag"),
386
+ priority: readListOptionString(options, "priority"),
387
+ deadlineBefore: readListOptionString(options, "deadlineBefore"),
388
+ deadlineAfter: readListOptionString(options, "deadlineAfter"),
389
+ assignee: readListOptionString(options, "assignee"),
390
+ assigneeFilter: readListOptionString(options, "assigneeFilter"),
391
+ parent: readListOptionString(options, "parent"),
392
+ sprint: readListOptionString(options, "sprint"),
393
+ release: readListOptionString(options, "release"),
394
+ };
395
+ }
396
+ export function normalizeDedupeAuditOptions(options) {
397
+ return {
398
+ mode: typeof options.mode === "string" ? options.mode : undefined,
399
+ status: typeof options.status === "string" ? options.status : undefined,
400
+ type: readListOptionString(options, "type"),
401
+ tag: readListOptionString(options, "tag"),
402
+ priority: readListOptionString(options, "priority"),
403
+ deadlineBefore: readListOptionString(options, "deadlineBefore"),
404
+ deadlineAfter: readListOptionString(options, "deadlineAfter"),
405
+ assignee: readListOptionString(options, "assignee"),
406
+ assigneeFilter: readListOptionString(options, "assigneeFilter"),
407
+ parent: readListOptionString(options, "parent"),
408
+ sprint: readListOptionString(options, "sprint"),
409
+ release: readListOptionString(options, "release"),
410
+ limit: readListOptionString(options, "limit"),
411
+ threshold: typeof options.threshold === "string" ? options.threshold : undefined,
412
+ };
413
+ }
414
+ export function printListJsonStream(commandName, result, globalOptions) {
415
+ setActiveCommandResult(result);
416
+ if (globalOptions.quiet) {
417
+ return;
418
+ }
419
+ const warnings = Array.isArray(result.warnings) ? result.warnings : [];
420
+ const metaPayload = {
421
+ type: "meta",
422
+ command: commandName,
423
+ count: result.count,
424
+ now: result.now,
425
+ filters: result.filters,
426
+ };
427
+ if (warnings.length > 0) {
428
+ metaPayload.warnings = warnings;
429
+ }
430
+ if (!writeStdout(`${JSON.stringify(metaPayload)}\n`)) {
431
+ return;
432
+ }
433
+ for (const item of result.items) {
434
+ if (!writeStdout(`${JSON.stringify({ type: "item", command: commandName, item })}\n`)) {
435
+ return;
436
+ }
437
+ }
438
+ writeStdout(`${JSON.stringify({ type: "end", command: commandName, count: result.count })}\n`);
439
+ }
440
+ export function printActivityJsonStream(result, options, globalOptions) {
441
+ setActiveCommandResult(result);
442
+ if (globalOptions.quiet) {
443
+ return;
444
+ }
445
+ const metaPayload = {
446
+ type: "meta",
447
+ command: "activity",
448
+ count: result.count,
449
+ filters: {
450
+ id: options.id ?? null,
451
+ op: options.op ?? null,
452
+ author: options.author ?? null,
453
+ from: options.from ?? null,
454
+ to: options.to ?? null,
455
+ limit: options.limit ?? null,
456
+ },
457
+ };
458
+ if (!writeStdout(`${JSON.stringify(metaPayload)}\n`)) {
459
+ return;
460
+ }
461
+ const entries = result.compact && result.compact_activity ? result.compact_activity : result.activity;
462
+ for (const entry of entries) {
463
+ if (!writeStdout(`${JSON.stringify({ type: "entry", command: "activity", entry })}\n`)) {
464
+ return;
465
+ }
466
+ }
467
+ writeStdout(`${JSON.stringify({ type: "end", command: "activity", count: result.count })}\n`);
468
+ }
469
+ export function normalizeSearchOptions(options) {
470
+ const readSearchString = (target) => readFirstStringFromCommanderOptions(options, SEARCH_COMMANDER_STRING_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
471
+ target,
472
+ keys: [target],
473
+ });
474
+ const fields = readSearchString("fields");
475
+ const compactRequested = options.compact === true;
476
+ const fullRequested = options.full === true;
477
+ const defaultCompact = !compactRequested && !fullRequested && fields === undefined;
478
+ const normalized = {
479
+ mode: readSearchString("mode"),
480
+ includeLinked: options.includeLinked === true ? true : undefined,
481
+ titleExact: options.titleExact === true ? true : undefined,
482
+ phraseExact: options.phraseExact === true ? true : undefined,
483
+ type: readSearchString("type"),
484
+ tag: readSearchString("tag"),
485
+ priority: readSearchString("priority"),
486
+ deadlineBefore: readSearchString("deadlineBefore"),
487
+ deadlineAfter: readSearchString("deadlineAfter"),
488
+ limit: readSearchString("limit"),
489
+ fields,
490
+ compact: compactRequested || defaultCompact ? true : undefined,
491
+ full: fullRequested ? true : undefined,
492
+ };
493
+ for (const [key, value] of Object.entries(options)) {
494
+ if (Object.hasOwn(normalized, key)) {
495
+ continue;
496
+ }
497
+ normalized[key] = value;
498
+ }
499
+ return normalized;
500
+ }
501
+ export function normalizeSearchKeywordsInput(keywords) {
502
+ const query = keywords
503
+ .map((entry) => entry.trim())
504
+ .filter((entry) => entry.length > 0)
505
+ .join(" ");
506
+ if (query.length === 0) {
507
+ throw new PmCliError("Search query must not be empty", EXIT_CODE.USAGE);
508
+ }
509
+ return query;
510
+ }
511
+ export function normalizeCalendarOptions(options) {
512
+ const readCalendarString = (target) => readFirstStringFromCommanderOptions(options, CALENDAR_COMMANDER_STRING_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
513
+ target,
514
+ keys: [target],
515
+ });
516
+ const normalized = {
517
+ view: readCalendarString("view"),
518
+ date: readCalendarString("date"),
519
+ from: readCalendarString("from"),
520
+ to: readCalendarString("to"),
521
+ past: options.past === true ? true : undefined,
522
+ fullPeriod: options.fullPeriod === true || options.full_period === true ? true : undefined,
523
+ limit: readCalendarString("limit"),
524
+ type: readCalendarString("type"),
525
+ tag: readCalendarString("tag"),
526
+ priority: readCalendarString("priority"),
527
+ status: readCalendarString("status"),
528
+ assignee: readCalendarString("assignee"),
529
+ assigneeFilter: readCalendarString("assigneeFilter"),
530
+ sprint: readCalendarString("sprint"),
531
+ release: readCalendarString("release"),
532
+ include: readCalendarString("include"),
533
+ recurrenceLookaheadDays: readCalendarString("recurrenceLookaheadDays"),
534
+ recurrenceLookbackDays: readCalendarString("recurrenceLookbackDays"),
535
+ occurrenceLimit: readCalendarString("occurrenceLimit"),
536
+ format: readCalendarString("format"),
537
+ };
538
+ for (const [key, value] of Object.entries(options)) {
539
+ if (Object.hasOwn(normalized, key)) {
540
+ continue;
541
+ }
542
+ normalized[key] = value;
543
+ }
544
+ return normalized;
545
+ }
546
+ export function normalizeActivityOptions(options) {
547
+ const readActivityString = (target) => readFirstStringFromCommanderOptions(options, ACTIVITY_COMMANDER_STRING_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
548
+ target,
549
+ keys: [target],
550
+ });
551
+ return {
552
+ id: readActivityString("id"),
553
+ op: readActivityString("op"),
554
+ author: readActivityString("author"),
555
+ from: readActivityString("from"),
556
+ to: readActivityString("to"),
557
+ limit: readActivityString("limit"),
558
+ compact: options.compact === true ? true : undefined,
559
+ };
560
+ }
561
+ export function resolveActivityStreamMode(raw) {
562
+ if (raw === true) {
563
+ return true;
564
+ }
565
+ if (raw === false || raw === undefined || raw === null) {
566
+ return false;
567
+ }
568
+ if (typeof raw === "string") {
569
+ const normalized = raw.trim().toLowerCase();
570
+ if (normalized.length === 0 ||
571
+ normalized === "rows" ||
572
+ normalized === "ndjson" ||
573
+ normalized === "jsonl" ||
574
+ normalized === "true" ||
575
+ normalized === "1" ||
576
+ normalized === "yes" ||
577
+ normalized === "on") {
578
+ return true;
579
+ }
580
+ if (normalized === "false" || normalized === "off" || normalized === "none" || normalized === "0") {
581
+ return false;
582
+ }
583
+ }
584
+ throw new PmCliError("Activity --stream accepts rows|ndjson|jsonl (or no value)", EXIT_CODE.USAGE);
585
+ }
586
+ export function normalizeContextOptions(options) {
587
+ const readContextString = (target) => readFirstStringFromCommanderOptions(options, CONTEXT_COMMANDER_STRING_OPTION_CONTRACTS.find((entry) => entry.target === target) ?? {
588
+ target,
589
+ keys: [target],
590
+ });
591
+ const sectionRaw = options.section;
592
+ const section = Array.isArray(sectionRaw)
593
+ ? sectionRaw.filter((v) => typeof v === "string" && v.trim().length > 0)
594
+ : typeof sectionRaw === "string" && sectionRaw.trim().length > 0
595
+ ? [sectionRaw]
596
+ : undefined;
597
+ const normalized = {
598
+ date: readContextString("date"),
599
+ from: readContextString("from"),
600
+ to: readContextString("to"),
601
+ past: options.past === true ? true : undefined,
602
+ type: readContextString("type"),
603
+ tag: readContextString("tag"),
604
+ priority: readContextString("priority"),
605
+ assignee: readContextString("assignee"),
606
+ assigneeFilter: readContextString("assigneeFilter"),
607
+ sprint: readContextString("sprint"),
608
+ release: readContextString("release"),
609
+ limit: readContextString("limit"),
610
+ format: readContextString("format"),
611
+ depth: readContextString("depth"),
612
+ section: section && section.length > 0 ? section : undefined,
613
+ activityLimit: readContextString("activityLimit"),
614
+ staleThreshold: readContextString("staleThreshold"),
615
+ };
616
+ for (const [key, value] of Object.entries(options)) {
617
+ if (Object.hasOwn(normalized, key)) {
618
+ continue;
619
+ }
620
+ normalized[key] = value;
621
+ }
622
+ return normalized;
623
+ }
624
+ function collectMutationItemIds(result) {
625
+ if (!result || typeof result !== "object") {
626
+ return [];
627
+ }
628
+ const record = result;
629
+ const ids = new Set();
630
+ const pushId = (value) => {
631
+ if (typeof value !== "string") {
632
+ return;
633
+ }
634
+ const normalized = value.trim();
635
+ if (normalized.length === 0) {
636
+ return;
637
+ }
638
+ ids.add(normalized);
639
+ };
640
+ pushId(record.id);
641
+ const item = record.item;
642
+ if (item && typeof item === "object") {
643
+ pushId(item.id);
644
+ }
645
+ const explicitIds = record.ids;
646
+ if (Array.isArray(explicitIds)) {
647
+ for (const candidate of explicitIds) {
648
+ pushId(candidate);
649
+ }
650
+ }
651
+ const items = record.items;
652
+ if (Array.isArray(items)) {
653
+ for (const candidate of items) {
654
+ if (!candidate || typeof candidate !== "object") {
655
+ continue;
656
+ }
657
+ pushId(candidate.id);
658
+ }
659
+ }
660
+ return [...ids].sort((left, right) => left.localeCompare(right));
661
+ }
662
+ export async function invalidateSearchCachesForMutation(globalOptions, result) {
663
+ const pmRoot = resolvePmRoot(process.cwd(), globalOptions.path);
664
+ const refreshResult = await refreshSearchArtifactsForMutation(pmRoot, collectMutationItemIds(result));
665
+ if (globalOptions.profile && refreshResult.warnings.length > 0) {
666
+ printError(`profile:search_refresh_warnings=${formatHookWarnings(refreshResult.warnings)}`);
667
+ }
668
+ }
669
+ //# sourceMappingURL=registration-helpers.js.map