@unbrained/pm-cli 2026.5.28 → 2026.5.30

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 (160) hide show
  1. package/CHANGELOG.md +127 -93
  2. package/dist/cli/bootstrap-args.d.ts +1 -1
  3. package/dist/cli/bootstrap-args.js +59 -9
  4. package/dist/cli/bootstrap-args.js.map +1 -1
  5. package/dist/cli/commander-usage.js +8 -8
  6. package/dist/cli/commander-usage.js.map +1 -1
  7. package/dist/cli/commands/activity.js +4 -4
  8. package/dist/cli/commands/activity.js.map +1 -1
  9. package/dist/cli/commands/aggregate.js +4 -3
  10. package/dist/cli/commands/aggregate.js.map +1 -1
  11. package/dist/cli/commands/calendar.d.ts +8 -0
  12. package/dist/cli/commands/calendar.js +15 -4
  13. package/dist/cli/commands/calendar.js.map +1 -1
  14. package/dist/cli/commands/close.js +4 -4
  15. package/dist/cli/commands/close.js.map +1 -1
  16. package/dist/cli/commands/completion.js +36 -4
  17. package/dist/cli/commands/completion.js.map +1 -1
  18. package/dist/cli/commands/config.d.ts +11 -1
  19. package/dist/cli/commands/config.js +68 -6
  20. package/dist/cli/commands/config.js.map +1 -1
  21. package/dist/cli/commands/create.d.ts +1 -0
  22. package/dist/cli/commands/create.js +55 -6
  23. package/dist/cli/commands/create.js.map +1 -1
  24. package/dist/cli/commands/deps.js +4 -4
  25. package/dist/cli/commands/deps.js.map +1 -1
  26. package/dist/cli/commands/extension/bundled-catalog.js +4 -3
  27. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -1
  28. package/dist/cli/commands/extension/install-sources.d.ts +1 -0
  29. package/dist/cli/commands/extension/install-sources.js +20 -2
  30. package/dist/cli/commands/extension/install-sources.js.map +1 -1
  31. package/dist/cli/commands/extension.js +26 -5
  32. package/dist/cli/commands/extension.js.map +1 -1
  33. package/dist/cli/commands/get.js +6 -3
  34. package/dist/cli/commands/get.js.map +1 -1
  35. package/dist/cli/commands/health.js +3 -11
  36. package/dist/cli/commands/health.js.map +1 -1
  37. package/dist/cli/commands/linked-test-parsers.js +5 -4
  38. package/dist/cli/commands/linked-test-parsers.js.map +1 -1
  39. package/dist/cli/commands/list.js +25 -6
  40. package/dist/cli/commands/list.js.map +1 -1
  41. package/dist/cli/commands/plan.js +5 -4
  42. package/dist/cli/commands/plan.js.map +1 -1
  43. package/dist/cli/commands/search.js +45 -2
  44. package/dist/cli/commands/search.js.map +1 -1
  45. package/dist/cli/commands/stats.js +4 -4
  46. package/dist/cli/commands/stats.js.map +1 -1
  47. package/dist/cli/commands/test-all.js +4 -4
  48. package/dist/cli/commands/test-all.js.map +1 -1
  49. package/dist/cli/commands/update-many.js +35 -6
  50. package/dist/cli/commands/update-many.js.map +1 -1
  51. package/dist/cli/commands/update.d.ts +2 -0
  52. package/dist/cli/commands/update.js +38 -6
  53. package/dist/cli/commands/update.js.map +1 -1
  54. package/dist/cli/help-json-payload.d.ts +1 -11
  55. package/dist/cli/help-json-payload.js +12 -12
  56. package/dist/cli/help-json-payload.js.map +1 -1
  57. package/dist/cli/main.d.ts +2 -0
  58. package/dist/cli/main.js +39 -11
  59. package/dist/cli/main.js.map +1 -1
  60. package/dist/cli/register-list-query.js +3 -3
  61. package/dist/cli/register-list-query.js.map +1 -1
  62. package/dist/cli/register-mutation.js +20 -8
  63. package/dist/cli/register-mutation.js.map +1 -1
  64. package/dist/cli/register-setup.js +4 -2
  65. package/dist/cli/register-setup.js.map +1 -1
  66. package/dist/cli/registration-helpers.d.ts +2 -6
  67. package/dist/cli/registration-helpers.js +9 -6
  68. package/dist/cli/registration-helpers.js.map +1 -1
  69. package/dist/cli-bundle/chunks/chunk-PB2YU2E3.js +164 -0
  70. package/dist/cli-bundle/chunks/chunk-PB2YU2E3.js.map +7 -0
  71. package/dist/cli-bundle/chunks/chunk-RJONRNXN.js +682 -0
  72. package/dist/cli-bundle/chunks/chunk-RJONRNXN.js.map +7 -0
  73. package/dist/cli-bundle/chunks/chunk-SW5BMMCU.js +13864 -0
  74. package/dist/cli-bundle/chunks/chunk-SW5BMMCU.js.map +7 -0
  75. package/dist/cli-bundle/chunks/commands-XJ4TJ5UN.js +24225 -0
  76. package/dist/cli-bundle/chunks/commands-XJ4TJ5UN.js.map +7 -0
  77. package/dist/cli-bundle/chunks/register-list-query-EIVQ5FMR.js +223 -0
  78. package/dist/cli-bundle/chunks/register-list-query-EIVQ5FMR.js.map +7 -0
  79. package/dist/cli-bundle/chunks/register-mutation-RSZNPSGI.js +702 -0
  80. package/dist/cli-bundle/chunks/register-mutation-RSZNPSGI.js.map +7 -0
  81. package/dist/cli-bundle/chunks/register-operations-APUSYDMR.js +355 -0
  82. package/dist/cli-bundle/chunks/register-operations-APUSYDMR.js.map +7 -0
  83. package/dist/cli-bundle/chunks/register-setup-OZOKSMPJ.js +237 -0
  84. package/dist/cli-bundle/chunks/register-setup-OZOKSMPJ.js.map +7 -0
  85. package/dist/cli-bundle/main.js +6896 -0
  86. package/dist/cli-bundle/main.js.map +7 -0
  87. package/dist/cli.js +1 -1
  88. package/dist/core/config/nested-settings.d.ts +88 -0
  89. package/dist/core/config/nested-settings.js +273 -0
  90. package/dist/core/config/nested-settings.js.map +1 -0
  91. package/dist/core/item/parse.d.ts +19 -0
  92. package/dist/core/item/parse.js +76 -2
  93. package/dist/core/item/parse.js.map +1 -1
  94. package/dist/core/item/priority.d.ts +2 -1
  95. package/dist/core/item/priority.js +12 -2
  96. package/dist/core/item/priority.js.map +1 -1
  97. package/dist/core/item/type-synonyms.d.ts +20 -0
  98. package/dist/core/item/type-synonyms.js +42 -0
  99. package/dist/core/item/type-synonyms.js.map +1 -0
  100. package/dist/core/search/cache.js +46 -4
  101. package/dist/core/search/cache.js.map +1 -1
  102. package/dist/core/search/providers.js +25 -5
  103. package/dist/core/search/providers.js.map +1 -1
  104. package/dist/core/search/semantic-defaults.js +73 -32
  105. package/dist/core/search/semantic-defaults.js.map +1 -1
  106. package/dist/core/search/staleness.d.ts +23 -0
  107. package/dist/core/search/staleness.js +34 -0
  108. package/dist/core/search/staleness.js.map +1 -0
  109. package/dist/core/search/vector-stores.js +12 -3
  110. package/dist/core/search/vector-stores.js.map +1 -1
  111. package/dist/core/sentry/helpers.d.ts +1 -1
  112. package/dist/core/sentry/helpers.js +4 -4
  113. package/dist/core/sentry/helpers.js.map +1 -1
  114. package/dist/core/shared/constants.js +3 -2
  115. package/dist/core/shared/constants.js.map +1 -1
  116. package/dist/core/shared/html-entity-decode.d.ts +22 -0
  117. package/dist/core/shared/html-entity-decode.js +127 -0
  118. package/dist/core/shared/html-entity-decode.js.map +1 -0
  119. package/dist/core/shared/split-comma-list.d.ts +20 -0
  120. package/dist/core/shared/split-comma-list.js +29 -0
  121. package/dist/core/shared/split-comma-list.js.map +1 -0
  122. package/dist/core/shared/time.js +52 -2
  123. package/dist/core/shared/time.js.map +1 -1
  124. package/dist/core/store/front-matter-cache.d.ts +24 -0
  125. package/dist/core/store/front-matter-cache.js +119 -8
  126. package/dist/core/store/front-matter-cache.js.map +1 -1
  127. package/dist/core/store/item-store.d.ts +7 -0
  128. package/dist/core/store/item-store.js +13 -3
  129. package/dist/core/store/item-store.js.map +1 -1
  130. package/dist/core/store/settings-validator.d.ts +1 -0
  131. package/dist/core/store/settings-validator.js +3 -2
  132. package/dist/core/store/settings-validator.js.map +1 -1
  133. package/dist/core/store/settings.js +19 -3
  134. package/dist/core/store/settings.js.map +1 -1
  135. package/dist/mcp/server.js +11 -4
  136. package/dist/mcp/server.js.map +1 -1
  137. package/dist/sdk/cli-contracts/commander-mutation-options.js +47 -11
  138. package/dist/sdk/cli-contracts/commander-mutation-options.js.map +1 -1
  139. package/dist/sdk/cli-contracts/tool-option-contracts.js +5 -2
  140. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
  141. package/dist/sdk/cli-contracts/tool-parameter-tables.js +12 -2
  142. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
  143. package/dist/sdk/cli-contracts.js +28 -7
  144. package/dist/sdk/cli-contracts.js.map +1 -1
  145. package/dist/sdk/runtime.d.ts +1 -1
  146. package/dist/sdk/runtime.js +3 -3
  147. package/dist/sdk/runtime.js.map +1 -1
  148. package/dist/types.d.ts +2 -0
  149. package/dist/types.js +2 -2
  150. package/dist/types.js.map +1 -1
  151. package/docs/AGENT_GUIDE.md +7 -0
  152. package/docs/COMMANDS.md +17 -0
  153. package/docs/CONFIGURATION.md +66 -0
  154. package/docs/QUICKSTART.md +3 -0
  155. package/package.json +7 -4
  156. package/packages/pm-calendar/extensions/calendar/index.js +27 -2
  157. package/packages/pm-calendar/extensions/calendar/index.ts +28 -2
  158. package/packages/pm-calendar/extensions/calendar/runtime.js +5 -0
  159. package/packages/pm-calendar/extensions/calendar/runtime.ts +6 -0
  160. package/scripts/bundle-cli.mjs +39 -0
@@ -1,17 +1,19 @@
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]="10f962f6-810b-5b40-a073-b763d0b0d8b0")}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]="a9e9e59a-9be5-5285-96a5-093e23264246")}catch(e){}}();
3
3
  import { pathExists, removeFileIfExists, writeFileAtomic } from "../../core/fs/fs-utils.js";
4
4
  import { appendHistoryEntry, createHistoryEntry } from "../../core/history/history.js";
5
5
  import { generateItemId, normalizeItemId } from "../../core/item/id.js";
6
6
  import { canonicalDocument, normalizeFrontMatter, serializeItemDocument } from "../../core/item/item-format.js";
7
7
  import { normalizeParentReferenceValue, validateMissingParentReference, } from "../../core/item/parent-reference-policy.js";
8
8
  import { validateSprintOrReleaseValue } from "../../core/item/sprint-release-format.js";
9
- import { createStdinTokenResolver, parseCsvKv, parseOptionalNumber, parseTags } from "../../core/item/parse.js";
9
+ import { createStdinTokenResolver, mergeAdditiveTags, parseCsvKv, parseOptionalNumber, parseTags } from "../../core/item/parse.js";
10
10
  import { resolvePriority } from "../../core/item/priority.js";
11
11
  import { normalizeStatusInput } from "../../core/item/status.js";
12
12
  import { canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, } from "../../core/item/type-registry.js";
13
13
  import { acquireLock } from "../../core/lock/lock.js";
14
+ import { printError } from "../../core/output/output.js";
14
15
  import { buildInvalidTypeError } from "../../core/schema/item-types-file.js";
16
+ import { resolveTypeSynonym } from "../../core/item/type-synonyms.js";
15
17
  import { collectRuntimeCreateFieldValues } from "../../core/schema/runtime-field-values.js";
16
18
  import { resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, } from "../../core/schema/runtime-schema.js";
17
19
  import { EXIT_CODE, FRONT_MATTER_KEY_ORDER } from "../../core/shared/constants.js";
@@ -711,6 +713,14 @@ function requireCreateOptionByType(typeDefinition, options, createMode, clearOpt
711
713
  typeOption: options.typeOption,
712
714
  };
713
715
  const hasOptionValue = (optionKey) => {
716
+ // `--add-tags` mutates the same `tags` field as `--tags`, so it must count
717
+ // toward the `tags` command_option_policy (both the disabled guard and the
718
+ // required check) — otherwise `--add-tags` would bypass a rule disabling
719
+ // tags, or fail to satisfy a rule requiring them even though the created
720
+ // item ends up tagged.
721
+ if (optionKey === "tags") {
722
+ return scalarValues.tags !== undefined || (Array.isArray(options.addTags) && options.addTags.length > 0);
723
+ }
714
724
  if (optionKey in scalarValues) {
715
725
  return scalarValues[optionKey] !== undefined;
716
726
  }
@@ -954,9 +964,21 @@ export async function runCreate(options, global) {
954
964
  if (resolvedOptions.type === undefined) {
955
965
  throw new PmCliError("Missing required option --type <value>", EXIT_CODE.USAGE);
956
966
  }
957
- const resolvedTypeName = resolveTypeName(resolvedOptions.type, typeRegistry);
967
+ let resolvedTypeName = resolveTypeName(resolvedOptions.type, typeRegistry);
958
968
  if (!resolvedTypeName) {
959
- throw new PmCliError(buildInvalidTypeError(resolvedOptions.type, typeRegistry.types), EXIT_CODE.USAGE);
969
+ // Never block on a near-miss type: map a known synonym (e.g. Bug -> Issue,
970
+ // Change -> Chore) to its canonical built-in type when that type exists in the
971
+ // active registry, and tell the agent how to make it a distinct custom type.
972
+ const synonymCanonical = resolveTypeSynonym(resolvedOptions.type);
973
+ const synonymResolved = synonymCanonical ? resolveTypeName(synonymCanonical, typeRegistry) : undefined;
974
+ if (synonymResolved) {
975
+ printError(`[pm] note: type '${resolvedOptions.type.trim()}' is not defined; using closest match '${synonymResolved}'. Run 'pm schema add-type "${resolvedOptions.type.trim()}"' to track it as a distinct type.`);
976
+ resolvedOptions.type = synonymResolved;
977
+ resolvedTypeName = synonymResolved;
978
+ }
979
+ else {
980
+ throw new PmCliError(buildInvalidTypeError(resolvedOptions.type, typeRegistry.types), EXIT_CODE.USAGE);
981
+ }
960
982
  }
961
983
  const typeDefinition = resolveTypeDefinition(resolvedTypeName, typeRegistry);
962
984
  if (!typeDefinition) {
@@ -1212,11 +1234,20 @@ export async function runCreate(options, global) {
1212
1234
  const id = await generateItemId(pmRoot, settings.id_prefix);
1213
1235
  let status = resolvedOptions.status !== undefined ? parseStatusValue(resolvedOptions.status, statusRegistry) : statusRegistry.open_status;
1214
1236
  const priority = resolvedOptions.priority !== undefined ? ensurePriority(resolvedOptions.priority) : 2;
1215
- const tags = unsetTargets.frontMatterKeys.has("tags")
1237
+ // `--unset tags` clears the field; combining it with `--add-tags` is the same
1238
+ // contradiction that `--unset tags --tags ...` already rejects, so reject it
1239
+ // here rather than silently letting the additions win over the clear.
1240
+ if (unsetTargets.frontMatterKeys.has("tags") &&
1241
+ Array.isArray(resolvedOptions.addTags) &&
1242
+ resolvedOptions.addTags.length > 0) {
1243
+ throw new PmCliError("Cannot combine --unset tags with --add-tags", EXIT_CODE.USAGE);
1244
+ }
1245
+ const baseTags = unsetTargets.frontMatterKeys.has("tags")
1216
1246
  ? []
1217
1247
  : resolvedOptions.tags !== undefined
1218
1248
  ? parseTags(resolvedOptions.tags)
1219
1249
  : [];
1250
+ const tags = mergeAdditiveTags(baseTags, resolvedOptions.addTags);
1220
1251
  const deadline = unsetTargets.frontMatterKeys.has("deadline")
1221
1252
  ? undefined
1222
1253
  : resolvedOptions.deadline === undefined
@@ -1288,6 +1319,16 @@ export async function runCreate(options, global) {
1288
1319
  if (type.toLowerCase() === "event" && (events.values === undefined || events.values.length === 0)) {
1289
1320
  validationWarnings.push(`event_without_schedule:${id}:no_time_set`);
1290
1321
  }
1322
+ // Calendar-relevant types (Milestone, Meeting, Reminder, Event) with NO deadline AND no
1323
+ // reminders AND no events are invisible on `pm calendar`. Warn (never block) so the agent
1324
+ // can attach a schedule via `pm update`.
1325
+ const calendarRelevantTypes = new Set(["milestone", "meeting", "reminder", "event"]);
1326
+ const hasDeadline = deadline !== undefined;
1327
+ const hasReminders = reminders.values !== undefined && reminders.values.length > 0;
1328
+ const hasEvents = events.values !== undefined && events.values.length > 0;
1329
+ if (calendarRelevantTypes.has(type.toLowerCase()) && !hasDeadline && !hasReminders && !hasEvents) {
1330
+ validationWarnings.push(`calendar_item_without_schedule:${id}:no_deadline_or_reminder_or_event`);
1331
+ }
1291
1332
  if (parent !== undefined) {
1292
1333
  parent = normalizeParentReferenceValue(parent);
1293
1334
  const parentLocated = await locateItem(pmRoot, parent, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
@@ -1497,6 +1538,14 @@ export async function runCreate(options, global) {
1497
1538
  }
1498
1539
  const changedFields = buildChangedFields(frontMatter, body, explicitUnsetKeys);
1499
1540
  const outputItem = structuredClone(frontMatter);
1541
+ // After the create has committed (so the ID is real and shows up in the suggestion),
1542
+ // emit a single non-blocking stderr hint when the new item would be invisible on `pm
1543
+ // calendar`. The structured `calendar_item_without_schedule:*` warning above is what
1544
+ // automation reads; this stderr line is the human/agent-facing version with a
1545
+ // copy-pasteable `pm update` recipe.
1546
+ if (calendarRelevantTypes.has(type.toLowerCase()) && !hasDeadline && !hasReminders && !hasEvents) {
1547
+ printError(`[pm] warning: ${type} '${id}' has no deadline/reminder/event — it will not appear on the calendar. Add one via 'pm update ${id} --deadline <ISO>' or 'pm update ${id} --event "start=<ISO>,end=<ISO>"'.`);
1548
+ }
1500
1549
  return {
1501
1550
  item: outputItem,
1502
1551
  changed_fields: changedFields,
@@ -1504,4 +1553,4 @@ export async function runCreate(options, global) {
1504
1553
  };
1505
1554
  }
1506
1555
  //# sourceMappingURL=create.js.map
1507
- //# debugId=10f962f6-810b-5b40-a073-b763d0b0d8b0
1556
+ //# debugId=a9e9e59a-9be5-5285-96a5-093e23264246