@unbrained/pm-cli 2026.5.28 → 2026.5.29

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 (83) hide show
  1. package/CHANGELOG.md +100 -83
  2. package/dist/cli/commander-usage.js +8 -8
  3. package/dist/cli/commander-usage.js.map +1 -1
  4. package/dist/cli/commands/aggregate.js +4 -3
  5. package/dist/cli/commands/aggregate.js.map +1 -1
  6. package/dist/cli/commands/calendar.d.ts +8 -0
  7. package/dist/cli/commands/calendar.js +13 -2
  8. package/dist/cli/commands/calendar.js.map +1 -1
  9. package/dist/cli/commands/completion.js +34 -2
  10. package/dist/cli/commands/completion.js.map +1 -1
  11. package/dist/cli/commands/config.d.ts +11 -1
  12. package/dist/cli/commands/config.js +68 -6
  13. package/dist/cli/commands/config.js.map +1 -1
  14. package/dist/cli/commands/create.d.ts +1 -0
  15. package/dist/cli/commands/create.js +40 -4
  16. package/dist/cli/commands/create.js.map +1 -1
  17. package/dist/cli/commands/extension/bundled-catalog.js +4 -3
  18. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -1
  19. package/dist/cli/commands/health.js +3 -11
  20. package/dist/cli/commands/health.js.map +1 -1
  21. package/dist/cli/commands/linked-test-parsers.js +5 -4
  22. package/dist/cli/commands/linked-test-parsers.js.map +1 -1
  23. package/dist/cli/commands/plan.js +5 -4
  24. package/dist/cli/commands/plan.js.map +1 -1
  25. package/dist/cli/commands/search.js +45 -2
  26. package/dist/cli/commands/search.js.map +1 -1
  27. package/dist/cli/commands/update-many.js +35 -6
  28. package/dist/cli/commands/update-many.js.map +1 -1
  29. package/dist/cli/commands/update.d.ts +2 -0
  30. package/dist/cli/commands/update.js +38 -6
  31. package/dist/cli/commands/update.js.map +1 -1
  32. package/dist/cli/help-json-payload.d.ts +1 -11
  33. package/dist/cli/help-json-payload.js +12 -12
  34. package/dist/cli/help-json-payload.js.map +1 -1
  35. package/dist/cli/register-mutation.js +20 -8
  36. package/dist/cli/register-mutation.js.map +1 -1
  37. package/dist/cli/register-setup.js +4 -2
  38. package/dist/cli/register-setup.js.map +1 -1
  39. package/dist/cli/registration-helpers.d.ts +2 -6
  40. package/dist/cli/registration-helpers.js +9 -6
  41. package/dist/cli/registration-helpers.js.map +1 -1
  42. package/dist/core/config/nested-settings.d.ts +86 -0
  43. package/dist/core/config/nested-settings.js +258 -0
  44. package/dist/core/config/nested-settings.js.map +1 -0
  45. package/dist/core/item/parse.d.ts +19 -0
  46. package/dist/core/item/parse.js +76 -2
  47. package/dist/core/item/parse.js.map +1 -1
  48. package/dist/core/item/priority.d.ts +2 -1
  49. package/dist/core/item/priority.js +12 -2
  50. package/dist/core/item/priority.js.map +1 -1
  51. package/dist/core/search/providers.js +25 -5
  52. package/dist/core/search/providers.js.map +1 -1
  53. package/dist/core/search/staleness.d.ts +23 -0
  54. package/dist/core/search/staleness.js +34 -0
  55. package/dist/core/search/staleness.js.map +1 -0
  56. package/dist/core/search/vector-stores.js +12 -3
  57. package/dist/core/search/vector-stores.js.map +1 -1
  58. package/dist/core/shared/html-entity-decode.d.ts +21 -0
  59. package/dist/core/shared/html-entity-decode.js +122 -0
  60. package/dist/core/shared/html-entity-decode.js.map +1 -0
  61. package/dist/core/shared/split-comma-list.d.ts +20 -0
  62. package/dist/core/shared/split-comma-list.js +29 -0
  63. package/dist/core/shared/split-comma-list.js.map +1 -0
  64. package/dist/mcp/server.js +10 -3
  65. package/dist/mcp/server.js.map +1 -1
  66. package/dist/sdk/cli-contracts/commander-mutation-options.js +47 -11
  67. package/dist/sdk/cli-contracts/commander-mutation-options.js.map +1 -1
  68. package/dist/sdk/cli-contracts/tool-option-contracts.js +5 -2
  69. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
  70. package/dist/sdk/cli-contracts/tool-parameter-tables.js +12 -2
  71. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
  72. package/dist/sdk/cli-contracts.js +25 -4
  73. package/dist/sdk/cli-contracts.js.map +1 -1
  74. package/dist/sdk/runtime.d.ts +1 -1
  75. package/dist/sdk/runtime.js +3 -3
  76. package/dist/sdk/runtime.js.map +1 -1
  77. package/docs/AGENT_GUIDE.md +7 -0
  78. package/docs/COMMANDS.md +17 -0
  79. package/docs/CONFIGURATION.md +55 -0
  80. package/docs/QUICKSTART.md +3 -0
  81. package/package.json +1 -1
  82. package/packages/pm-calendar/extensions/calendar/runtime.js +5 -0
  83. package/packages/pm-calendar/extensions/calendar/runtime.ts +6 -0
@@ -1,3 +1,4 @@
1
+ import { type NestedSettingDescriptor } from "../../core/config/nested-settings.js";
1
2
  import type { GlobalOptions } from "../../core/shared/command-types.js";
2
3
  import type { GovernanceCloseValidationDefault, GovernanceCreateModeDefault, GovernanceOwnershipEnforcement, GovernancePreset, ItemFormat, ParentReferencePolicy, SprintReleaseFormatPolicy, ValidateMetadataProfile } from "../../types/index.js";
3
4
  declare const CONFIG_SCOPE_VALUES: readonly ["project", "global"];
@@ -26,6 +27,7 @@ export interface ConfigCommandOptions {
26
27
  criterion?: string[];
27
28
  format?: string;
28
29
  policy?: string;
30
+ value?: string;
29
31
  clearCriteria?: boolean;
30
32
  defaultDepth?: string;
31
33
  activityLimit?: string;
@@ -39,12 +41,20 @@ export interface ConfigCommandOptions {
39
41
  sectionStaleness?: string;
40
42
  sectionTests?: string;
41
43
  }
44
+ export interface NestedSettingResultValue {
45
+ key: string;
46
+ path: string;
47
+ kind: NestedSettingDescriptor["kind"];
48
+ value: string | number | null;
49
+ }
42
50
  export interface ConfigResult {
43
51
  scope: ConfigScope;
44
- key?: ConfigKey;
52
+ key?: ConfigKey | string;
45
53
  criteria?: string[];
46
54
  format?: ItemFormat;
47
55
  policy?: HistoryMissingStreamPolicy | SprintReleaseFormatPolicy | ParentReferencePolicy | ValidateMetadataProfile | GovernancePreset | GovernanceOwnershipEnforcement | GovernanceCreateModeDefault | GovernanceCloseValidationDefault | GovernanceForceRequiredForStaleLockPolicy | TestResultTrackingPolicy | TelemetryTrackingPolicy;
56
+ nested_setting?: NestedSettingResultValue;
57
+ nested_settings?: NestedSettingResultValue[];
48
58
  keys?: ConfigKeyDescriptor[];
49
59
  values?: Record<ConfigKey, ConfigValue>;
50
60
  count?: number;
@@ -1,7 +1,8 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5de8e394-f1b2-56ce-9de4-d33ee76eaaa9")}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]="d29673f1-c80f-54ca-a854-6e9abd634001")}catch(e){}}();
3
3
  import { pathExists } from "../../core/fs/fs-utils.js";
4
4
  import { resolveConfigPositionalValue } from "../../core/config/positional-value.js";
5
+ import { NESTED_SETTING_DESCRIPTORS, parseNestedSettingValue, readNestedSettingValue, resolveNestedSettingDescriptor, writeNestedSettingValue, } from "../../core/config/nested-settings.js";
5
6
  import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
6
7
  import { normalizeParentReferencePolicy } from "../../core/item/parent-reference-policy.js";
7
8
  import { normalizeSprintReleaseFormatPolicy } from "../../core/item/sprint-release-format.js";
@@ -218,7 +219,8 @@ function normalizeKey(value) {
218
219
  }
219
220
  return "definition_of_done";
220
221
  }
221
- throw new PmCliError(`Invalid config key "${value}". Supported: ${CANONICAL_CONFIG_KEYS.join(", ")} (underscore variants also accepted)`, EXIT_CODE.USAGE);
222
+ const nestedKeys = NESTED_SETTING_DESCRIPTORS.map((descriptor) => descriptor.key).join(", ");
223
+ throw new PmCliError(`Invalid config key "${value}". Supported: ${CANONICAL_CONFIG_KEYS.join(", ")} (underscore variants also accepted). Nested leaf settings: ${nestedKeys}.`, EXIT_CODE.USAGE);
222
224
  }
223
225
  function normalizeCriteria(values, clearCriteria) {
224
226
  const normalized = [...new Set((values ?? []).map((value) => value.trim()).filter((value) => value.length > 0))].sort((left, right) => left.localeCompare(right));
@@ -584,7 +586,7 @@ async function applyContextConfig(settings, options, target, scope, warnings) {
584
586
  * working exactly as before: a positional value is only injected when its flag was
585
587
  * not already supplied, and a conflicting explicit flag is a clear error.
586
588
  */
587
- function applyPositionalValue(action, keyValue, normalizedKey, valueValue, options) {
589
+ function applyPositionalValue(action, keyValue, normalizedKey, nestedSetting, valueValue, options) {
588
590
  if (valueValue === undefined) {
589
591
  return options;
590
592
  }
@@ -594,6 +596,13 @@ function applyPositionalValue(action, keyValue, normalizedKey, valueValue, optio
594
596
  if (typeof keyValue !== "string" || keyValue.trim().length === 0) {
595
597
  throw new PmCliError('Config action "set" requires <key> before a positional <value>.', EXIT_CODE.USAGE);
596
598
  }
599
+ if (nestedSetting) {
600
+ if (options.value !== undefined && valueValue !== undefined && options.value !== valueValue) {
601
+ throw new PmCliError(`Config set ${keyValue} received both positional value "${valueValue}" and --value "${options.value}". Pass only one.`, EXIT_CODE.USAGE);
602
+ }
603
+ // Pick whichever was supplied; do not overwrite a present --value with undefined.
604
+ return { ...options, value: valueValue ?? options.value };
605
+ }
597
606
  const routed = resolveConfigPositionalValue(normalizedKey ?? keyValue, valueValue);
598
607
  if (!routed.routable) {
599
608
  throw new PmCliError(routed.reason, EXIT_CODE.USAGE);
@@ -622,11 +631,57 @@ function applyPositionalValue(action, keyValue, normalizedKey, valueValue, optio
622
631
  export async function runConfig(scopeValue, actionValue, keyValue, options, global, valueValue) {
623
632
  const scope = normalizeScope(scopeValue);
624
633
  const action = normalizeAction(actionValue);
625
- const key = normalizeKeyForAction(action, keyValue);
626
- options = applyPositionalValue(action, keyValue, key, valueValue, options);
634
+ // Nested leaf settings (search/provider/vector-store) are detected before
635
+ // normalizeKey so they bypass the ConfigKey union without breaking the
636
+ // existing key-not-found error path for actually-unknown keys.
637
+ const nestedSetting = (action === "get" || action === "set") ? resolveNestedSettingDescriptor(keyValue) : undefined;
638
+ const key = nestedSetting ? undefined : normalizeKeyForAction(action, keyValue);
639
+ options = applyPositionalValue(action, keyValue, key, nestedSetting, valueValue, options);
627
640
  const target = await resolveSettingsTarget(scope, global);
628
641
  const { settings, metadata, warnings: settingsReadWarnings } = await readSettingsWithMetadata(target.pmRoot);
629
642
  const warnings = normalizeWarnings(settingsReadWarnings);
643
+ if (nestedSetting) {
644
+ if (action === "get") {
645
+ const currentValue = readNestedSettingValue(settings, nestedSetting);
646
+ return withWarnings({
647
+ scope,
648
+ key: nestedSetting.key,
649
+ nested_setting: {
650
+ key: nestedSetting.key,
651
+ path: nestedSetting.path,
652
+ kind: nestedSetting.kind,
653
+ value: currentValue,
654
+ },
655
+ settings_path: target.settingsPath,
656
+ changed: false,
657
+ }, warnings);
658
+ }
659
+ // action === "set"
660
+ const rawValue = options.value;
661
+ if (typeof rawValue !== "string") {
662
+ throw new PmCliError(`Config set ${nestedSetting.key} requires a value. Pass it positionally (\`pm config ${scope} set ${nestedSetting.key} <value>\`) or via --value.`, EXIT_CODE.USAGE);
663
+ }
664
+ const parsed = parseNestedSettingValue(nestedSetting, rawValue);
665
+ if (!parsed.ok) {
666
+ throw new PmCliError(parsed.error.message, EXIT_CODE.USAGE);
667
+ }
668
+ const changed = writeNestedSettingValue(settings, nestedSetting, parsed.parsed.value);
669
+ if (changed) {
670
+ await writeSettings(target.pmRoot, settings, `config:set:${nestedSetting.path}`);
671
+ }
672
+ return withWarnings({
673
+ scope,
674
+ key: nestedSetting.key,
675
+ nested_setting: {
676
+ key: nestedSetting.key,
677
+ path: nestedSetting.path,
678
+ kind: nestedSetting.kind,
679
+ value: parsed.parsed.value,
680
+ },
681
+ settings_path: target.settingsPath,
682
+ changed,
683
+ }, warnings);
684
+ }
630
685
  if (action === "list") {
631
686
  const keys = Object.keys(CONFIG_KEY_ALIASES).map((candidate) => ({
632
687
  key: candidate,
@@ -640,9 +695,16 @@ export async function runConfig(scopeValue, actionValue, keyValue, options, glob
640
695
  summary: CONFIG_KEY_SUMMARIES[candidate],
641
696
  value: readConfigValue(settings, candidate),
642
697
  }));
698
+ const nestedSettings = NESTED_SETTING_DESCRIPTORS.map((descriptor) => ({
699
+ key: descriptor.key,
700
+ path: descriptor.path,
701
+ kind: descriptor.kind,
702
+ value: readNestedSettingValue(settings, descriptor),
703
+ }));
643
704
  return withWarnings({
644
705
  scope,
645
706
  keys,
707
+ nested_settings: nestedSettings,
646
708
  count: keys.length,
647
709
  settings_path: target.settingsPath,
648
710
  changed: false,
@@ -1224,4 +1286,4 @@ export async function runConfig(scopeValue, actionValue, keyValue, options, glob
1224
1286
  }, warnings);
1225
1287
  }
1226
1288
  //# sourceMappingURL=config.js.map
1227
- //# debugId=5de8e394-f1b2-56ce-9de4-d33ee76eaaa9
1289
+ //# debugId=d29673f1-c80f-54ca-a854-6e9abd634001