@unbrained/pm-cli 2026.8.26 → 2026.8.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/.agents/skills/HARNESS_COMPATIBILITY.md +32 -0
  2. package/.agents/skills/README.md +47 -0
  3. package/.agents/skills/pm-developer/SKILL.md +117 -0
  4. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +49 -0
  5. package/.agents/skills/pm-developer/references/GRAPH_AND_RELATIONSHIPS.md +91 -0
  6. package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +72 -0
  7. package/.agents/skills/pm-developer/references/PROMPTS.md +17 -0
  8. package/.agents/skills/pm-developer/references/SCRIPTING_COMPOSITION.md +82 -0
  9. package/.agents/skills/pm-developer/references/TOKEN_BUDGETS.md +85 -0
  10. package/.agents/skills/pm-extensions/SKILL.md +106 -0
  11. package/.agents/skills/pm-extensions/references/AUTHORING.md +95 -0
  12. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +40 -0
  13. package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +25 -0
  14. package/.agents/skills/pm-sdk/SKILL.md +107 -0
  15. package/.agents/skills/pm-sdk/references/DOMAIN_MODELING.md +78 -0
  16. package/.agents/skills/pm-sdk/references/INTEGRATION_CHECKLIST.md +31 -0
  17. package/.agents/skills/pm-sdk/references/PROMPTS.md +13 -0
  18. package/.agents/skills/pm-sdk/references/SURFACE_MAP.md +82 -0
  19. package/.agents/skills/pm-user/SKILL.md +111 -0
  20. package/.agents/skills/pm-user/references/BACKLOG_SHAPING.md +105 -0
  21. package/.agents/skills/pm-user/references/PROMPTS.md +17 -0
  22. package/.agents/skills/pm-user/references/WORKFLOWS.md +35 -0
  23. package/.claude-plugin/marketplace.json +2 -2
  24. package/CHANGELOG.md +50 -4
  25. package/README.md +8 -5
  26. package/dist/cli/commander-usage.js +11 -7
  27. package/dist/cli/error-guidance.js +62 -8
  28. package/dist/cli/help-content.d.ts +2 -0
  29. package/dist/cli/help-content.js +53 -17
  30. package/dist/cli/help-json-payload.d.ts +8 -2
  31. package/dist/cli/help-json-payload.js +46 -12
  32. package/dist/cli/main.js +52 -74
  33. package/dist/cli/register-annotations.js +83 -60
  34. package/dist/cli/register-setup.js +98 -57
  35. package/dist/cli-bundle/bundle-manifest.json +151 -151
  36. package/dist/cli-bundle/chunks/{chunk-UKBCRPA2.js → chunk-BY2FQ2NI.js} +2 -2
  37. package/dist/cli-bundle/chunks/chunk-E73FDIWT.js +3 -0
  38. package/dist/cli-bundle/chunks/{chunk-WRHJ3MB6.js → chunk-FEVBFFCQ.js} +2 -2
  39. package/dist/cli-bundle/chunks/{chunk-KBFP3E4E.js → chunk-M7OXRQE3.js} +66 -44
  40. package/dist/cli-bundle/chunks/{chunk-S4U76VZF.js → chunk-NBCBFVZI.js} +2 -2
  41. package/dist/cli-bundle/chunks/{chunk-ZNRLJ54C.js → chunk-NTXZHRKA.js} +45 -45
  42. package/dist/cli-bundle/chunks/chunk-QE6WQXFO.js +3 -0
  43. package/dist/cli-bundle/chunks/chunk-TIQ6AMH2.js +13 -0
  44. package/dist/cli-bundle/chunks/chunk-X2RROGZE.js +2 -0
  45. package/dist/cli-bundle/chunks/{chunk-E2GCFJSU.js → chunk-XRVVYRRO.js} +33 -33
  46. package/dist/cli-bundle/chunks/chunk-XWEQGHHG.js +202 -0
  47. package/dist/cli-bundle/chunks/{register-list-query-EMCPMICY.js → register-list-query-J35ZPQQ5.js} +2 -2
  48. package/dist/cli-bundle/chunks/{register-mutation-OJ67ABCB.js → register-mutation-J6XJJOGU.js} +4 -4
  49. package/dist/cli-bundle/chunks/{register-operations-H2GLP7LT.js → register-operations-AE3JEMFT.js} +2 -2
  50. package/dist/cli-bundle/chunks/register-setup-OQERLLWE.js +2 -0
  51. package/dist/cli-bundle/focused-chunks/{chunk-72T6JGAE.js → chunk-4ZDRZYYJ.js} +43 -43
  52. package/dist/cli-bundle/focused-chunks/{chunk-OHIHZ7HS.js → chunk-6GCRSLPG.js} +2 -2
  53. package/dist/cli-bundle/focused-chunks/{chunk-UYBA57GY.js → chunk-AD6ULRAF.js} +2 -2
  54. package/dist/cli-bundle/focused-chunks/{chunk-FXDLT6FL.js → chunk-AHAM2HAU.js} +2 -2
  55. package/dist/cli-bundle/focused-chunks/{chunk-LV5N3LK5.js → chunk-FC2AXLB5.js} +2 -2
  56. package/dist/cli-bundle/focused-chunks/{chunk-IBHXMFE7.js → chunk-HC7ODMH3.js} +2 -2
  57. package/dist/cli-bundle/focused-chunks/{chunk-4K2II4TV.js → chunk-HVQ22RC4.js} +2 -2
  58. package/dist/cli-bundle/focused-chunks/{chunk-MMXUPDDJ.js → chunk-JZYPPMXF.js} +2 -2
  59. package/dist/cli-bundle/focused-chunks/chunk-LLNTHF5X.js +2 -0
  60. package/dist/cli-bundle/focused-chunks/chunk-LYFWQMVC.js +2 -0
  61. package/dist/cli-bundle/focused-chunks/{chunk-A644DUFQ.js → chunk-MEASX544.js} +2 -2
  62. package/dist/cli-bundle/focused-chunks/{chunk-YO3ZF3FI.js → chunk-THEPQMLX.js} +2 -2
  63. package/dist/cli-bundle/focused-chunks/{chunk-57XY346D.js → chunk-XDPYBQCF.js} +9 -9
  64. package/dist/cli-bundle/focused-chunks/{chunk-TMJDFHVD.js → chunk-Y3JJXRVK.js} +2 -2
  65. package/dist/cli-bundle/focused-chunks/{chunk-66VGB23P.js → chunk-Y5A7SJJ7.js} +2 -2
  66. package/dist/cli-bundle/focused-chunks/chunk-YJLDHJOD.js +2 -0
  67. package/dist/cli-bundle/focused-chunks/{chunk-P2E6LDAE.js → chunk-YVVZ3LQ6.js} +3 -3
  68. package/dist/cli-bundle/focused-chunks/chunk-Z2USIBR2.js +5 -0
  69. package/dist/cli-bundle/main.js +15 -14
  70. package/dist/cli-bundle/sdk-authoring.js +1 -1
  71. package/dist/cli-bundle/sdk-contracts.js +2 -2
  72. package/dist/cli-bundle/sdk-core.js +31 -31
  73. package/dist/cli-bundle/sdk-governance.js +1 -1
  74. package/dist/cli-bundle/sdk-graph.js +1 -1
  75. package/dist/cli-bundle/sdk-merge.js +31 -31
  76. package/dist/cli-bundle/sdk-query.js +1 -1
  77. package/dist/cli-bundle/sdk-runtime.js +1 -1
  78. package/dist/cli-bundle/sdk-testing.js +1 -1
  79. package/dist/cli-bundle/sdk.js +32 -7
  80. package/dist/core/governance/issue-codes.d.ts +11 -2
  81. package/dist/core/governance/issue-codes.js +29 -10
  82. package/dist/core/item/item-format.js +3 -3
  83. package/dist/core/store/item-store.js +12 -5
  84. package/dist/mcp/server.js +123 -9
  85. package/dist/mcp/tool-definitions.d.ts +2 -0
  86. package/dist/mcp/tool-definitions.js +5 -5
  87. package/dist/sdk/agent/closed-domain-contracts.d.ts +1 -1
  88. package/dist/sdk/agent/closed-domain-contracts.js +24 -2
  89. package/dist/sdk/agent/command-recovery.js +3 -3
  90. package/dist/sdk/agent/task-transcript-contracts.d.ts +52 -0
  91. package/dist/sdk/agent/task-transcript-contracts.js +198 -0
  92. package/dist/sdk/agent-capability-contracts.js +6 -2
  93. package/dist/sdk/annotations.d.ts +5 -2
  94. package/dist/sdk/annotations.js +66 -36
  95. package/dist/sdk/cli-bootstrap.d.ts +2 -8
  96. package/dist/sdk/cli-bootstrap.js +7 -66
  97. package/dist/sdk/cli-contracts/bootstrap-command-scanner.d.ts +23 -0
  98. package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +80 -0
  99. package/dist/sdk/cli-contracts/command-aliases.js +15 -2
  100. package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -1
  101. package/dist/sdk/cli-contracts/enum-contracts.js +7 -2
  102. package/dist/sdk/cli-contracts/flag-contracts.js +12 -5
  103. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +5 -5
  104. package/dist/sdk/cli-contracts/grammar-contracts.d.ts +3 -3
  105. package/dist/sdk/cli-contracts/grammar-contracts.js +24 -17
  106. package/dist/sdk/cli-contracts/runtime-contracts.js +13 -11
  107. package/dist/sdk/cli-contracts/tool-parameter-tables.js +15 -2
  108. package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
  109. package/dist/sdk/cli-contracts/tool-schema.js +32 -16
  110. package/dist/sdk/cli-contracts.d.ts +1 -1
  111. package/dist/sdk/cli-contracts.js +3 -3
  112. package/dist/sdk/cli-program.js +3 -2
  113. package/dist/sdk/comments.d.ts +4 -0
  114. package/dist/sdk/comments.js +2 -2
  115. package/dist/sdk/completion.js +47 -16
  116. package/dist/sdk/contracts.d.ts +1 -0
  117. package/dist/sdk/contracts.js +3 -2
  118. package/dist/sdk/extension/install-sources.d.ts +13 -0
  119. package/dist/sdk/extension/install-sources.js +62 -30
  120. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +26 -2
  121. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +38 -14
  122. package/dist/sdk/governance/upgrade.d.ts +2 -0
  123. package/dist/sdk/governance/upgrade.js +30 -8
  124. package/dist/sdk/governance/validate.js +8 -6
  125. package/dist/sdk/guide-topics.js +6 -6
  126. package/dist/sdk/index.d.ts +5 -2
  127. package/dist/sdk/index.js +6 -3
  128. package/dist/sdk/learnings.d.ts +4 -0
  129. package/dist/sdk/learnings.js +7 -4
  130. package/dist/sdk/lifecycle/close.js +4 -3
  131. package/dist/sdk/mcp/apps.d.ts +70 -0
  132. package/dist/sdk/mcp/apps.js +154 -0
  133. package/dist/sdk/mcp/skills.d.ts +127 -0
  134. package/dist/sdk/mcp/skills.js +390 -0
  135. package/dist/sdk/notes.d.ts +4 -0
  136. package/dist/sdk/notes.js +2 -2
  137. package/dist/sdk/read-output-contracts.js +16 -3
  138. package/dist/sdk/runtime-action-aliases.js +7 -3
  139. package/dist/sdk/runtime-input.js +15 -4
  140. package/dist/sdk/runtime-primitives.d.ts +1 -1
  141. package/dist/sdk/runtime-primitives.js +3 -3
  142. package/dist/sdk/runtime.d.ts +6 -6
  143. package/dist/sdk/runtime.js +8 -8
  144. package/docs/CLI_GRAMMAR.md +7 -1
  145. package/docs/COMMANDS.md +5 -4
  146. package/docs/EXTENSIONS.md +33 -32
  147. package/docs/MCP_2026_07_28.md +24 -2
  148. package/docs/MCP_2026_07_28_CONFORMANCE.md +4 -4
  149. package/docs/MCP_SKILLS_AND_APPS.md +107 -0
  150. package/docs/OUTPUT_TOKEN_ACCOUNTING.md +20 -7
  151. package/docs/QUICKSTART.md +15 -15
  152. package/docs/README.md +1 -0
  153. package/docs/RELEASING.md +20 -4
  154. package/docs/SDK.md +12 -0
  155. package/docs/SDK_CONTEXT_INTEGRITY.md +18 -1
  156. package/docs/SDK_EVIDENCE_TRACEABILITY.md +9 -1
  157. package/docs/SDK_RUNTIME_BOUNDARIES.md +10 -0
  158. package/docs/TESTING.md +6 -2
  159. package/docs/agent-task-token-baseline.json +97 -11
  160. package/docs/agent-task-transcripts.json +211 -0
  161. package/docs/generated/AGENT_CAPABILITY_ROUTING.md +1 -1
  162. package/docs/generated/FLAG_LEXICON_BUDGETS.md +3 -3
  163. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +11 -7
  164. package/docs/performance/cli-transport-overhead.md +10 -2
  165. package/marketplace.json +2 -2
  166. package/package.json +10 -8
  167. package/packages/pm-beads/README.md +12 -6
  168. package/packages/pm-beads/docs/MIGRATION.md +53 -0
  169. package/packages/pm-beads/extensions/beads/index.ts +8 -0
  170. package/packages/pm-beads/extensions/beads/runtime.ts +671 -112
  171. package/packages/pm-beads/package.json +1 -1
  172. package/packages/pm-calendar/package.json +1 -1
  173. package/packages/pm-command-kit/package.json +1 -1
  174. package/packages/pm-digital-twin/package.json +1 -1
  175. package/packages/pm-governance-audit/package.json +1 -1
  176. package/packages/pm-guide-shell/package.json +1 -1
  177. package/packages/pm-kanban/package.json +1 -1
  178. package/packages/pm-lifecycle-hooks/package.json +1 -1
  179. package/packages/pm-linked-test-adapters/package.json +1 -1
  180. package/packages/pm-search-advanced/package.json +1 -1
  181. package/packages/pm-templates/package.json +1 -1
  182. package/packages/pm-todos/package.json +1 -1
  183. package/packages/pm-vcs/package.json +1 -1
  184. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  185. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  186. package/sdk/public-surface.json +430 -36
  187. package/dist/cli-bundle/chunks/chunk-ES25LX3D.js +0 -202
  188. package/dist/cli-bundle/chunks/chunk-FRDWWB6R.js +0 -3
  189. package/dist/cli-bundle/chunks/chunk-ICQ3RVIY.js +0 -2
  190. package/dist/cli-bundle/chunks/chunk-IV64RJVE.js +0 -13
  191. package/dist/cli-bundle/chunks/chunk-MVYLQ67M.js +0 -3
  192. package/dist/cli-bundle/chunks/register-setup-GLZAHLVI.js +0 -2
  193. package/dist/cli-bundle/focused-chunks/chunk-4XNH2HM7.js +0 -2
  194. package/dist/cli-bundle/focused-chunks/chunk-7I23XGWO.js +0 -2
  195. package/dist/cli-bundle/focused-chunks/chunk-7YCDTCBC.js +0 -2
  196. package/dist/cli-bundle/focused-chunks/chunk-LMKG3DFE.js +0 -5
@@ -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]="79bf0b3f-ad63-5d9f-9911-d5a142214ac1")}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]="775518a4-ff3e-5a54-8fbd-b2c4863e23db")}catch(e){}}();
3
3
  import { EXIT_CODE, PmCliError, } from "../sdk/runtime-primitives.js";
4
4
  import { renderPmCommand } from "../sdk/command-line.js";
5
5
  import { runComments } from "./commands/comments.js";
@@ -11,6 +11,7 @@ function assertNoTransposedAnnotationAction(collection, id, text, options) {
11
11
  return;
12
12
  }
13
13
  const suppliedText = readOptionString(options, "add") ??
14
+ readOptionString(options, "text") ??
14
15
  readOptionString(options, "note") ??
15
16
  readOptionString(options, "body") ??
16
17
  readOptionString(options, "comment");
@@ -25,12 +26,7 @@ function assertNoTransposedAnnotationAction(collection, id, text, options) {
25
26
  else
26
27
  retryArgs.push("--add", "-");
27
28
  const suggestedRetry = renderPmCommand(retryArgs);
28
- const stdinRetry = renderPmCommand([
29
- collection,
30
- text.trim(),
31
- "--add",
32
- "-",
33
- ]);
29
+ const stdinRetry = renderPmCommand([collection, text.trim(), "--add", "-"]);
34
30
  throw new PmCliError(`The positional token "add" was parsed as the item id, while "${text.trim()}" was parsed as annotation text. ${collection} does not use an add subcommand.`, EXIT_CODE.USAGE, {
35
31
  code: "annotation_transposed_subcommand",
36
32
  reason: "noun_verb_object_transposition",
@@ -47,12 +43,26 @@ function assertNoTransposedAnnotationAction(collection, id, text, options) {
47
43
  },
48
44
  });
49
45
  }
46
+ function resolveAnnotationTextAliases(label, options, aliases) {
47
+ const supplied = aliases.flatMap((alias) => {
48
+ const value = readOptionString(options, alias);
49
+ return value === undefined ? [] : [{ alias, value }];
50
+ });
51
+ const distinctValues = [...new Set(supplied.map(({ value }) => value))];
52
+ if (distinctValues.length > 1) {
53
+ throw new PmCliError(`Specify ${label} text with one alias or the same value across aliases: ${supplied.map(({ alias }) => `--${alias}`).join(", ")}`, EXIT_CODE.USAGE, { code: "annotation_alias_conflict" });
54
+ }
55
+ return supplied[0]?.value;
56
+ }
50
57
  function resolveCommentSources(text, options) {
51
58
  const editIndex = typeof options.edit === "number" ? options.edit : undefined;
52
59
  const deleteIndex = typeof options.delete === "number" ? options.delete : undefined;
53
- const addFromOption = readOptionString(options, "add") ??
54
- readOptionString(options, "body") ??
55
- readOptionString(options, "comment");
60
+ const addFromOption = resolveAnnotationTextAliases("comment", options, [
61
+ "add",
62
+ "text",
63
+ "body",
64
+ "comment",
65
+ ]);
56
66
  const addFromPositional = typeof text === "string" ? text : undefined;
57
67
  const readFromStdin = options.stdin === true;
58
68
  const readFromFile = readOptionString(options, "file");
@@ -83,20 +93,33 @@ function resolveCommentSources(text, options) {
83
93
  deleteIndex !== undefined,
84
94
  };
85
95
  }
86
- function resolveSingleTextSource(label, positional, options) {
87
- const canonicalAdd = readOptionString(options, "add");
88
- const aliasAdd = label === "note" ? readOptionString(options, "note") : undefined;
89
- if (canonicalAdd !== undefined &&
90
- aliasAdd !== undefined &&
91
- canonicalAdd !== aliasAdd) {
92
- throw new PmCliError("Specify note text with either --add or --note, not conflicting values for both aliases", EXIT_CODE.USAGE, { code: "annotation_alias_conflict" });
93
- }
94
- const addFromOption = canonicalAdd ?? aliasAdd;
96
+ /** Resolves every mutation-bearing source for notes and learnings once. */
97
+ function resolveSingleAnnotationSources(label, positional, options) {
98
+ const addFromOption = resolveAnnotationTextAliases(label, options, label === "note" ? ["add", "text", "note"] : ["add", "text"]);
95
99
  const addFromPositional = typeof positional === "string" ? positional : undefined;
96
100
  if (addFromOption !== undefined && addFromPositional !== undefined) {
97
101
  throw new PmCliError(`Specify ${label} text either as positional [text] or with --add, not both`, EXIT_CODE.USAGE);
98
102
  }
99
- return addFromOption ?? addFromPositional;
103
+ const add = addFromOption ?? addFromPositional;
104
+ const addJson = label === "note" ? readOptionString(options, "addJson") : undefined;
105
+ const readFromStdin = options.stdin === true;
106
+ const readFromFile = readOptionString(options, "file");
107
+ const editIndex = typeof options.edit === "number" ? options.edit : undefined;
108
+ const deleteIndex = typeof options.delete === "number" ? options.delete : undefined;
109
+ return {
110
+ add,
111
+ addJson,
112
+ readFromStdin,
113
+ readFromFile,
114
+ editIndex,
115
+ deleteIndex,
116
+ isMutation: typeof add === "string" ||
117
+ addJson !== undefined ||
118
+ readFromStdin ||
119
+ readFromFile !== undefined ||
120
+ editIndex !== undefined ||
121
+ deleteIndex !== undefined,
122
+ };
100
123
  }
101
124
  async function runCommentsAction(id, text, options, command) {
102
125
  const globalOptions = getGlobalOptions(command);
@@ -111,12 +134,13 @@ async function runCommentsAction(id, text, options, command) {
111
134
  delete: sources.deleteIndex,
112
135
  limit: readOptionString(options, "limit"),
113
136
  fullHistory: options.fullHistory === true,
137
+ ifAbsent: options.ifAbsent === true,
114
138
  author: readOptionString(options, "author"),
115
139
  message: readOptionString(options, "message"),
116
140
  ownershipAppendBypass: options.ownershipAppendBypass === true,
117
141
  force: Boolean(options.force),
118
142
  }, globalOptions);
119
- if (sources.isMutation) {
143
+ if (sources.isMutation && result.changed !== false) {
120
144
  await invalidateSearchCachesForMutation(globalOptions, result);
121
145
  }
122
146
  printAnnotationResult("comments", result, globalOptions, startedAt);
@@ -125,30 +149,26 @@ async function runNotesAction(id, text, options, command) {
125
149
  const globalOptions = getGlobalOptions(command);
126
150
  const startedAt = Date.now();
127
151
  assertNoTransposedAnnotationAction("notes", id, text, options);
128
- const add = resolveSingleTextSource("note", text, options);
152
+ const sources = resolveSingleAnnotationSources("note", text, options);
129
153
  const result = await runNotes(id, {
130
- add,
131
- addJson: readOptionString(options, "addJson"),
132
- stdin: options.stdin === true,
133
- file: readOptionString(options, "file"),
134
- edit: typeof options.edit === "number" ? options.edit : undefined,
135
- delete: typeof options.delete === "number" ? options.delete : undefined,
154
+ add: sources.add,
155
+ addJson: sources.addJson,
156
+ stdin: sources.readFromStdin,
157
+ file: sources.readFromFile,
158
+ edit: sources.editIndex,
159
+ delete: sources.deleteIndex,
136
160
  limit: readOptionString(options, "limit"),
137
161
  since: readOptionString(options, "since"),
138
162
  eventType: readOptionString(options, "eventType"),
139
163
  includeMeta: options.includeMeta === true,
140
164
  fullHistory: options.fullHistory === true,
165
+ ifAbsent: options.ifAbsent === true,
141
166
  author: readOptionString(options, "author"),
142
167
  message: readOptionString(options, "message"),
143
168
  ownershipAppendBypass: options.ownershipAppendBypass === true,
144
169
  force: Boolean(options.force),
145
170
  }, globalOptions);
146
- if (typeof add === "string" ||
147
- typeof options.addJson === "string" ||
148
- options.stdin === true ||
149
- typeof options.file === "string" ||
150
- typeof options.edit === "number" ||
151
- typeof options.delete === "number") {
171
+ if (sources.isMutation && result.changed !== false) {
152
172
  await invalidateSearchCachesForMutation(globalOptions, result);
153
173
  }
154
174
  printAnnotationResult("notes", result, globalOptions, startedAt);
@@ -157,25 +177,22 @@ async function runLearningsAction(id, text, options, command) {
157
177
  const globalOptions = getGlobalOptions(command);
158
178
  const startedAt = Date.now();
159
179
  assertNoTransposedAnnotationAction("learnings", id, text, options);
160
- const add = resolveSingleTextSource("learning", text, options);
180
+ const sources = resolveSingleAnnotationSources("learning", text, options);
161
181
  const result = await runLearnings(id, {
162
- add,
163
- stdin: options.stdin === true,
164
- file: readOptionString(options, "file"),
165
- edit: typeof options.edit === "number" ? options.edit : undefined,
166
- delete: typeof options.delete === "number" ? options.delete : undefined,
182
+ add: sources.add,
183
+ stdin: sources.readFromStdin,
184
+ file: sources.readFromFile,
185
+ edit: sources.editIndex,
186
+ delete: sources.deleteIndex,
167
187
  limit: readOptionString(options, "limit"),
168
188
  fullHistory: options.fullHistory === true,
189
+ ifAbsent: options.ifAbsent === true,
169
190
  author: readOptionString(options, "author"),
170
191
  message: readOptionString(options, "message"),
171
192
  ownershipAppendBypass: options.ownershipAppendBypass === true,
172
193
  force: Boolean(options.force),
173
194
  }, globalOptions);
174
- if (typeof add === "string" ||
175
- options.stdin === true ||
176
- typeof options.file === "string" ||
177
- typeof options.edit === "number" ||
178
- typeof options.delete === "number") {
195
+ if (sources.isMutation && result.changed !== false) {
179
196
  await invalidateSearchCachesForMutation(globalOptions, result);
180
197
  }
181
198
  printAnnotationResult("learnings", result, globalOptions, startedAt);
@@ -192,27 +209,29 @@ export function registerAnnotationCommands(program, parsePositiveInteger) {
192
209
  .command("comments")
193
210
  .argument("<id>", "Item id")
194
211
  .argument("[text]", "Optional comment text shorthand (equivalent to --add)")
195
- .option("--add <text>", "Add one comment entry (plain text fallback, text=<value>, markdown pairs, or - for stdin; CSV-like key fragments are preserved as plain text unless text is explicit)")
212
+ .option("--add <text>", "Append comment text; use text=<value> for structured input or - for stdin")
196
213
  .option("--stdin", "Read comment text from stdin (supports multiline markdown)")
197
214
  .option("--file <path>", "Read comment text from a file or stdin (-)")
198
- .option("--edit <index>", "Replace the comment at 1-based <index> (replacement text from positional [text], --add, --stdin, or --file)", parsePositiveInteger("--edit"))
215
+ .option("--edit <index>", "Replace one comment using positional text, --add, --stdin, or --file", parsePositiveInteger("--edit"))
199
216
  .option("--delete <index>", "Delete the comment at 1-based <index>", parsePositiveInteger("--delete"))
200
217
  .option("--limit <n>", "Return only latest n comments")
201
- .option("--full-history", "Return the complete post-mutation comment history instead of a bounded receipt")
202
- .option("--author [value]", "Comment author (optional; falls back to PM_AUTHOR/settings)")
218
+ .option("--full-history", "Return complete comment history instead of a bounded mutation receipt")
219
+ .option("--if-absent", "Append only when resolved author and text are absent")
220
+ .option("--author [value]", "Comment author; defaults to PM_AUTHOR or settings")
203
221
  .option("--message <value>", "History message")
204
222
  .option("--force", "Force ownership override")
205
223
  .description("List, add, edit, or delete comments for an item.")
206
224
  .action(runCommentsAction);
207
225
  addHiddenOption(commentsCommand, "--body <text>", "Alias for --add", false);
226
+ addHiddenOption(commentsCommand, "--text <text>", "Alias for --add", false);
208
227
  addHiddenOption(commentsCommand, "--comment <text>", "Alias for --add", false);
209
- program
228
+ const notesCommand = program
210
229
  .command("notes")
211
230
  .argument("<id>", "Item id")
212
- .argument("[text]", "Optional note text shorthand (equivalent to --add; use - for stdin)")
231
+ .argument("[text]", "Optional note text shorthand for --add")
213
232
  .option("--add <text>", "Add a text note (- reads stdin)")
214
233
  .option("--note <text>", "Alias for --add")
215
- .option("--add-json <json>", "Append a merge-safe JSON event")
234
+ .option("--add-json <json>", "Append a JSON event")
216
235
  .option("--stdin", "Read note text from stdin")
217
236
  .option("--file <path>", "Read note from file or stdin (-)")
218
237
  .option("--edit <index>", "Replace a 1-based note using the selected text input", parsePositiveInteger("--edit"))
@@ -221,28 +240,32 @@ export function registerAnnotationCommands(program, parsePositiveInteger) {
221
240
  .option("--since <timestamp>", "Filter JSON events from this ISO time")
222
241
  .option("--event-type <value>", "Filter JSON events by top-level type")
223
242
  .option("--include-meta", "Include count and truncation metadata")
224
- .option("--full-history", "Return the complete post-mutation note history instead of a bounded receipt")
243
+ .option("--full-history", "Return complete note history instead of a bounded receipt")
244
+ .option("--if-absent", "Append only when resolved author and text are absent")
225
245
  .option("--author [value]", "Author; defaults to PM_AUTHOR/settings")
226
246
  .option("--message <value>", "History message")
227
247
  .option("--force", "Force ownership override")
228
248
  .description("Manage merge-safe text notes and JSON context events.")
229
249
  .action(runNotesAction);
230
- program
250
+ addHiddenOption(notesCommand, "--text <text>", "Alias for --add", false);
251
+ const learningsCommand = program
231
252
  .command("learnings")
232
253
  .argument("<id>", "Item id")
233
- .argument("[text]", "Optional learning text shorthand (equivalent to --add; use - for stdin)")
234
- .option("--add <text>", "Add one learning entry (plain text fallback, text=<value>, markdown pairs, or - for stdin; CSV-like key fragments are preserved as plain text unless text is explicit)")
235
- .option("--stdin", "Read learning text from stdin (supports multiline markdown)")
254
+ .argument("[text]", "Optional learning text shorthand for --add")
255
+ .option("--add <text>", "Append learning text; use text=<value> or - for stdin")
256
+ .option("--stdin", "Read learning text from stdin")
236
257
  .option("--file <path>", "Read learning text from a file or stdin (-)")
237
- .option("--edit <index>", "Replace the learning at 1-based <index> (replacement text from positional [text], --add, --stdin, or --file)", parsePositiveInteger("--edit"))
258
+ .option("--edit <index>", "Replace one learning using positional text, --add, --stdin, or --file", parsePositiveInteger("--edit"))
238
259
  .option("--delete <index>", "Delete the learning at 1-based <index>", parsePositiveInteger("--delete"))
239
260
  .option("--limit <n>", "Return only latest n learnings")
240
- .option("--full-history", "Return the complete post-mutation learning history instead of a bounded receipt")
261
+ .option("--full-history", "Return complete learning history instead of a bounded receipt")
262
+ .option("--if-absent", "Append only when resolved author and text are absent")
241
263
  .option("--author [value]", "Learning author (optional; falls back to PM_AUTHOR/settings)")
242
264
  .option("--message <value>", "History message")
243
265
  .option("--force", "Force ownership override")
244
266
  .description("List, add, edit, or delete learnings for an item.")
245
267
  .action(runLearningsAction);
268
+ addHiddenOption(learningsCommand, "--text <text>", "Alias for --add", false);
246
269
  }
247
270
  //# sourceMappingURL=register-annotations.js.map
248
- //# debugId=79bf0b3f-ad63-5d9f-9911-d5a142214ac1
271
+ //# debugId=775518a4-ff3e-5a54-8fbd-b2c4863e23db
@@ -1,8 +1,9 @@
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]="2a7939ad-52a6-5d9c-b7cf-2bc59a6b3d32")}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]="feb682f9-344c-569e-bbab-861fe20f08f1")}catch(e){}}();
3
3
  import fs from "node:fs/promises";
4
4
  import path from "node:path";
5
- import { EXIT_CODE, PmCliError, } from "../sdk/runtime-primitives.js";
5
+ import { EXIT_CODE, PmCliError, readSettings, resolvePmRoot, } from "../sdk/runtime-primitives.js";
6
+ import { renderPmCommandAliasMigrationHint, resolvePmCommandAlias, } from "../sdk/cli-contracts.js";
6
7
  import { collect, getGlobalOptions, printError, printResult, writeStdout, } from "./registration-helpers.js";
7
8
  import { runExtension, } from "./commands/extension.js";
8
9
  import { SCAFFOLD_CAPABILITIES } from "./commands/extension/scaffold.js";
@@ -10,6 +11,20 @@ import { renderExtensionDescribeMarkdown, } from "./commands/extension/describe.
10
11
  import { runConfig } from "./commands/config.js";
11
12
  import { runInit, summarizeInitResult } from "./commands/init.js";
12
13
  import { runUpgrade } from "./commands/upgrade.js";
14
+ const LIFECYCLE_DEPRECATION_ALIASES = {
15
+ extension: "extension",
16
+ package: undefined,
17
+ };
18
+ async function emitDeprecatedAliasHint(alias, command) {
19
+ if (!alias)
20
+ return;
21
+ const aliasContract = resolvePmCommandAlias(alias);
22
+ const globalOptions = getGlobalOptions(command);
23
+ const deprecationHints = await readSettings(resolvePmRoot(process.cwd(), globalOptions.path)).then((settings) => settings.ux.deprecation_hints);
24
+ if (deprecationHints) {
25
+ printError(renderPmCommandAliasMigrationHint(aliasContract));
26
+ }
27
+ }
13
28
  const EXTENSION_ACTION_OPTION_KEYS = {
14
29
  init: "init",
15
30
  install: "install",
@@ -181,7 +196,9 @@ function applyExtensionDoctorStrictExit(result, normalizedOptions) {
181
196
  async function executeExtensionCommand(target, options, command, forcedAction, vocabulary = "extension") {
182
197
  const globalOptions = getGlobalOptions(command);
183
198
  const startedAt = Date.now();
184
- const normalizedOptions = normalizeExtensionOptions(options, forcedAction, vocabulary);
199
+ const effectiveVocabulary = vocabulary === "extension" ? "package" : vocabulary;
200
+ await emitDeprecatedAliasHint(LIFECYCLE_DEPRECATION_ALIASES[vocabulary], command);
201
+ const normalizedOptions = normalizeExtensionOptions(options, forcedAction, effectiveVocabulary);
185
202
  const outputOption = typeof normalizedOptions.output === "string"
186
203
  ? normalizedOptions.output
187
204
  : undefined;
@@ -191,7 +208,7 @@ async function executeExtensionCommand(target, options, command, forcedAction, v
191
208
  if (normalizedOptions.markdown === true) {
192
209
  await emitExtensionMarkdownResult({
193
210
  result,
194
- vocabulary,
211
+ vocabulary: effectiveVocabulary,
195
212
  outputPath,
196
213
  globalOptions,
197
214
  });
@@ -225,36 +242,13 @@ function serializeExtensionInstallError(error) {
225
242
  exit_code: EXIT_CODE.GENERIC_FAILURE,
226
243
  };
227
244
  }
228
- async function executeExtensionInstallCommand(targets, options, command, vocabulary) {
229
- const normalizedTargets = await normalizeInstallTargets(targets);
230
- if (normalizedTargets === undefined || normalizedTargets.length <= 1) {
231
- await executeExtensionCommand(normalizedTargets?.[0], options, command, "install", vocabulary);
232
- return;
233
- }
234
- const globalOptions = getGlobalOptions(command);
235
- const startedAt = Date.now();
236
- const normalizedOptions = normalizeExtensionOptions(options, "install", vocabulary);
237
- validateExtensionMarkdownOptions(normalizedOptions, globalOptions, undefined);
238
- const hasForcedGithubSource = [
239
- normalizedOptions.gh,
240
- normalizedOptions.github,
241
- ].some((value) => typeof value === "string" && value.trim().length > 0);
242
- if (hasForcedGithubSource) {
243
- throw new PmCliError("Multiple install targets cannot be combined with --gh/--github. Install one GitHub source per command, or pass multiple explicit local, bundled, or npm: targets.", EXIT_CODE.USAGE, {
244
- code: "multi_target_github_install_ambiguous",
245
- required: "Use exactly one positional target with --gh/--github, or omit --gh/--github when installing multiple targets.",
246
- examples: [
247
- "pm install --gh owner/repo",
248
- "pm install npm:pm-guide-shell pm-todos",
249
- ],
250
- });
251
- }
245
+ async function runMultiTargetExtensionInstalls(targets, options, globalOptions) {
252
246
  const rows = [];
253
247
  const warnings = [];
254
248
  let failureExitCode = EXIT_CODE.GENERIC_FAILURE;
255
- for (const target of normalizedTargets) {
249
+ for (const target of targets) {
256
250
  try {
257
- const result = await runExtension(target, normalizedOptions, globalOptions);
251
+ const result = await runExtension(target, options, globalOptions);
258
252
  const details = extractExtensionInstallDetails(result);
259
253
  const targetWarnings = Array.isArray(result.warnings)
260
254
  ? result.warnings
@@ -302,6 +296,35 @@ async function executeExtensionInstallCommand(targets, options, command, vocabul
302
296
  });
303
297
  }
304
298
  }
299
+ return { rows, warnings, failureExitCode };
300
+ }
301
+ async function executeExtensionInstallCommand(targets, options, command, vocabulary) {
302
+ const effectiveVocabulary = vocabulary === "extension" ? "package" : vocabulary;
303
+ await emitDeprecatedAliasHint(LIFECYCLE_DEPRECATION_ALIASES[vocabulary], command);
304
+ const normalizedTargets = await normalizeInstallTargets(targets);
305
+ if (normalizedTargets === undefined || normalizedTargets.length <= 1) {
306
+ await executeExtensionCommand(normalizedTargets?.[0], options, command, "install", effectiveVocabulary);
307
+ return;
308
+ }
309
+ const globalOptions = getGlobalOptions(command);
310
+ const startedAt = Date.now();
311
+ const normalizedOptions = normalizeExtensionOptions(options, "install", effectiveVocabulary);
312
+ validateExtensionMarkdownOptions(normalizedOptions, globalOptions, undefined);
313
+ const hasForcedGithubSource = [
314
+ normalizedOptions.gh,
315
+ normalizedOptions.github,
316
+ ].some((value) => typeof value === "string" && value.trim().length > 0);
317
+ if (hasForcedGithubSource) {
318
+ throw new PmCliError("Multiple install targets cannot be combined with --gh/--github. Install one GitHub source per command, or pass multiple explicit local, bundled, or npm: targets.", EXIT_CODE.USAGE, {
319
+ code: "multi_target_github_install_ambiguous",
320
+ required: "Use exactly one positional target with --gh/--github, or omit --gh/--github when installing multiple targets.",
321
+ examples: [
322
+ "pm install --gh owner/repo",
323
+ "pm install npm:pm-guide-shell pm-todos",
324
+ ],
325
+ });
326
+ }
327
+ const { rows, warnings, failureExitCode } = await runMultiTargetExtensionInstalls(normalizedTargets, normalizedOptions, globalOptions);
305
328
  const failedCount = rows.filter((row) => row.ok !== true).length;
306
329
  const result = {
307
330
  ok: failedCount === 0,
@@ -337,17 +360,41 @@ function addLifecycleScopeOptions(command, vocabulary) {
337
360
  ? addPackageScopeOptions(command)
338
361
  : addExtensionScopeOptions(command);
339
362
  }
363
+ function addUpgradeOptions(command) {
364
+ return command
365
+ .option("--dry-run", "Plan CLI/package upgrades without running npm or reinstalling packages")
366
+ .option("--cli-only", "Upgrade only the pm CLI/SDK npm package")
367
+ .option("--packages-only", "Upgrade only managed pm packages")
368
+ .option("--repair", "Force npm global reinstall when upgrading the pm CLI/SDK")
369
+ .option("--tag <value>", "npm dist-tag/version for CLI and registry package upgrades")
370
+ .option("--package-name <value>", "Override the CLI package name for self-upgrade testing");
371
+ }
372
+ async function executeUpgradeCommand(target, command, legacyAlias) {
373
+ const globalOptions = getGlobalOptions(command);
374
+ const startedAt = Date.now();
375
+ if (legacyAlias) {
376
+ await emitDeprecatedAliasHint("upgrade", command);
377
+ }
378
+ const result = await runUpgrade(target, command.opts(), globalOptions);
379
+ printResult(result, globalOptions);
380
+ if (!result.ok) {
381
+ process.exitCode = EXIT_CODE.GENERIC_FAILURE;
382
+ }
383
+ if (globalOptions.profile) {
384
+ printError(`profile:command=package-upgrade took_ms=${Date.now() - startedAt}`);
385
+ }
386
+ }
340
387
  function registerLifecycleCommand(program, vocabulary) {
341
388
  const noun = vocabulary === "package" ? "package" : "extension";
342
389
  const plural = vocabulary === "package" ? "packages" : "extensions";
343
390
  const commandName = vocabulary;
344
391
  const lifecycleCommand = program
345
- .command(commandName)
346
- .argument("[target]", `${noun[0].toUpperCase()}${noun.slice(1)} source/name or scaffold target path (for --init/--scaffold)`)
392
+ .command(commandName, { hidden: vocabulary === "extension" })
393
+ .argument("[target]", `${noun[0].toUpperCase()}${noun.slice(1)} source, name, or scaffold path`)
347
394
  .option("--init", `Generate a starter ${noun} scaffold at target path`)
348
395
  .option("--scaffold", "Alias for --init")
349
- .option("--capability <kind>", `Capability the --init starter targets (${SCAFFOLD_CAPABILITIES.join("|")}; default commands)`, collect)
350
- .option("--install", `Install ${noun} from local path, bundled alias, npm: source, wildcard, or GitHub source`)
396
+ .option("--capability <kind>", "Starter capability for --init (default: commands)", collect)
397
+ .option("--install", `Install a ${noun} source`)
351
398
  .option("--uninstall", `Uninstall an installed ${noun}`)
352
399
  .option("--explore", `List discovered ${plural} in selected scope`)
353
400
  .option("--list", "Alias for --explore")
@@ -378,8 +425,8 @@ function registerLifecycleCommand(program, vocabulary) {
378
425
  .option("--strict-exit", "Return non-zero exit when doctor warnings are present (ok=false)")
379
426
  .option("--fail-on-warn", "Alias for --strict-exit (doctor)")
380
427
  .description(vocabulary === "package"
381
- ? "Manage package lifecycle operations for project or global scope. Backward-compatible with extension packages."
382
- : "Manage extension lifecycle operations for project or global scope.")
428
+ ? "Manage package lifecycle in project or global scope."
429
+ : "Manage extension lifecycle in project or global scope.")
383
430
  .action(async (target, _options, command) => {
384
431
  await executeExtensionCommand(target, command.optsWithGlobals(), command, undefined, vocabulary);
385
432
  });
@@ -499,6 +546,14 @@ function registerLifecycleCommand(program, vocabulary) {
499
546
  .description(`Deactivate a ${noun} in selected scope settings.`), vocabulary).action(async (target, _options, command) => {
500
547
  await executeExtensionCommand(target, command.optsWithGlobals(), command, "deactivate", vocabulary);
501
548
  });
549
+ if (vocabulary === "package") {
550
+ addUpgradeOptions(addPackageScopeOptions(lifecycleCommand
551
+ .command("upgrade")
552
+ .argument("[target]", "Optional managed package name/source to upgrade; omit to upgrade pm CLI and all managed packages")
553
+ .description("Upgrade the pm CLI/SDK and refresh managed installable pm packages."))).action(async (target, _options, command) => {
554
+ await executeUpgradeCommand(target, command, false);
555
+ });
556
+ }
502
557
  }
503
558
  async function runInitCommandAction(prefix, options, command) {
504
559
  const globalOptions = getGlobalOptions(command);
@@ -642,35 +697,21 @@ export function registerSetupCommands(program) {
642
697
  registerLifecycleCommand(program, "extension");
643
698
  registerLifecycleCommand(program, "package");
644
699
  addPackageScopeOptions(program
645
- .command("install")
700
+ .command("install", { hidden: true })
646
701
  .argument("[targets...]", "Package source (local path, bundled alias, npm: source, wildcard, or GitHub source)")
647
702
  .option("--gh <github-source>", "Install from GitHub shorthand source (owner/repo[/path])")
648
703
  .option("--github <github-source>", "Alias for --gh")
649
704
  .option("--ref <ref>", "Git ref/branch/tag for GitHub install sources")
650
705
  .description("Install a pm package into the project package scope by default.")).action(async (targets, _options, command) => {
706
+ await emitDeprecatedAliasHint("install", command);
651
707
  await executeExtensionInstallCommand(targets, command.optsWithGlobals(), command, "package");
652
708
  });
653
- addPackageScopeOptions(program
654
- .command("upgrade")
709
+ addUpgradeOptions(addPackageScopeOptions(program
710
+ .command("upgrade", { hidden: true })
655
711
  .argument("[target]", "Optional managed package name/source to upgrade; omit to upgrade pm CLI and all managed packages")
656
- .option("--dry-run", "Plan CLI/package upgrades without running npm or reinstalling packages")
657
- .option("--cli-only", "Upgrade only the pm CLI/SDK npm package")
658
- .option("--packages-only", "Upgrade only managed pm packages")
659
- .option("--repair", "Force npm global reinstall when upgrading the pm CLI/SDK")
660
- .option("--tag <value>", "npm dist-tag/version for CLI and registry package upgrades")
661
- .option("--package-name <value>", "Override the CLI package name for self-upgrade testing")
662
- .description("Upgrade the pm CLI/SDK and refresh managed installable pm packages.")).action(async (target, _options, command) => {
663
- const globalOptions = getGlobalOptions(command);
664
- const startedAt = Date.now();
665
- const result = await runUpgrade(target, command.opts(), globalOptions);
666
- printResult(result, globalOptions);
667
- if (!result.ok) {
668
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
669
- }
670
- if (globalOptions.profile) {
671
- printError(`profile:command=upgrade took_ms=${Date.now() - startedAt}`);
672
- }
712
+ .description("Upgrade the pm CLI/SDK and refresh managed installable pm packages."))).action(async (target, _options, command) => {
713
+ await executeUpgradeCommand(target, command, true);
673
714
  });
674
715
  }
675
716
  //# sourceMappingURL=register-setup.js.map
676
- //# debugId=2a7939ad-52a6-5d9c-b7cf-2bc59a6b3d32
717
+ //# debugId=feb682f9-344c-569e-bbab-861fe20f08f1