@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
@@ -30,6 +30,8 @@ export interface NotesCommandOptions {
30
30
  includeMeta?: boolean;
31
31
  /** Return complete note history after a mutation instead of a bounded receipt. */
32
32
  fullHistory?: boolean;
33
+ /** Append only when no note has the same resolved author and text. */
34
+ ifAbsent?: boolean;
33
35
  /** Value that configures or reports author for this contract. */
34
36
  author?: string;
35
37
  /** Human-readable explanation suitable for logs and agent-facing output. */
@@ -59,6 +61,8 @@ export interface NotesResult {
59
61
  mutation_receipt?: AnnotationMutationReceipt;
60
62
  /** Declares whether older notes were withheld from a mutation response. */
61
63
  omission_receipt?: AnnotationOmissionReceipt;
64
+ /** Whether a requested mutation changed persisted state. */
65
+ changed?: boolean;
62
66
  }
63
67
  /** Implements run notes for the public runtime surface of this module. */
64
68
  export declare function runNotes(id: string, options: NotesCommandOptions, global: GlobalOptions): Promise<NotesResult>;
package/dist/sdk/notes.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Implements the pm notes command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ebd9f151-593f-5081-97da-d78f83de4914")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="216389a2-fb85-56a0-8ef2-9f41f1321c16")}catch(e){}}();
8
8
  import { EXIT_CODE, PmCliError, parseLimit, stableStringify, } from "./runtime-primitives.js";
9
9
  import { limitAnnotationEntries, parseAnnotationTextInput, resolveAnnotationInput, runAnnotationCommand, } from "./annotations.js";
10
10
  function parseStructuredEventPayload(raw) {
@@ -137,4 +137,4 @@ export async function runNotes(id, options, global) {
137
137
  };
138
138
  }
139
139
  //# sourceMappingURL=notes.js.map
140
- //# debugId=ebd9f151-593f-5081-97da-d78f83de4914
140
+ //# debugId=216389a2-fb85-56a0-8ef2-9f41f1321c16
@@ -5,7 +5,7 @@
5
5
  * surface without coupling package authors to command-specific option names.
6
6
  */
7
7
 
8
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d084da05-c967-58f1-afe4-069f09838e6f")}catch(e){}}();
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="2103a4dc-3037-5768-b2c7-5964de4ac86b")}catch(e){}}();
9
9
  import { EXIT_CODE } from "../core/shared/constants.js";
10
10
  import { PmCliError } from "../core/shared/errors.js";
11
11
  import { compactReadOutputToBudget, estimateReadOutputTokens, resolveReadOutputRecoveryBudget, updateReadOutputReceiptEstimate, } from "./read-output-budget.js";
@@ -388,7 +388,20 @@ export function applyReadOutputIncludeModes(command, includeValue, commandOption
388
388
  modes.push(token);
389
389
  canonicalModes.add(token);
390
390
  }
391
- if (modes.length > 0) {
391
+ const forwardedGetFieldSelectors = resolveReadOutputSurface(command) === "get"
392
+ ? selectors.filter((selector) => selector !== "item")
393
+ : [];
394
+ const forwardedGetFields = forwardedGetFieldSelectors.length > 0;
395
+ if (forwardedGetFields) {
396
+ commandOptions.fields = [
397
+ ...new Set([
398
+ ...(stringList(commandOptions.fields) ?? []),
399
+ ...forwardedGetFieldSelectors,
400
+ ]),
401
+ ].join(",");
402
+ canonicalModes.add("fields");
403
+ }
404
+ if (modes.length > 0 || forwardedGetFields) {
392
405
  optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE] = {
393
406
  canonical_include_modes: [...canonicalModes],
394
407
  explicit_legacy_aliases: [...explicitLegacyAliases],
@@ -1210,4 +1223,4 @@ export function resolveReadOutputEncoding(command, options) {
1210
1223
  : undefined;
1211
1224
  }
1212
1225
  //# sourceMappingURL=read-output-contracts.js.map
1213
- //# debugId=d084da05-c967-58f1-afe4-069f09838e6f
1226
+ //# debugId=2103a4dc-3037-5768-b2c7-5964de4ac86b
@@ -4,8 +4,8 @@
4
4
  * Declares canonical native-action routes for public SDK aliases.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6f62939a-7b99-5687-93ae-834e0032f1d5")}catch(e){}}();
8
- import { PM_EXTENSION_PACKAGE_ACTION_SUBCOMMANDS } from "./cli-contracts/enum-contracts.js";
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1ff4005f-be23-5dcf-9834-dbd7d083b76d")}catch(e){}}();
8
+ import { PM_EXTENSION_PACKAGE_ACTION_SUBCOMMANDS, PM_PACKAGE_ONLY_ACTION_SUBCOMMANDS, } from "./cli-contracts/enum-contracts.js";
9
9
  const LIST_ACTION_ALIASES = {
10
10
  "list-all": { action: "list", options: { excludeTerminal: false } },
11
11
  "list-draft": {
@@ -51,6 +51,10 @@ export const SDK_ACTION_ALIASES = {
51
51
  ...LIST_ACTION_ALIASES,
52
52
  ...buildExtensionPackageActionAliases("extension"),
53
53
  ...buildExtensionPackageActionAliases("package"),
54
+ ...Object.fromEntries(PM_PACKAGE_ONLY_ACTION_SUBCOMMANDS.map((subcommand) => [
55
+ `package-${subcommand}`,
56
+ { action: subcommand },
57
+ ])),
54
58
  };
55
59
  //# sourceMappingURL=runtime-action-aliases.js.map
56
- //# debugId=6f62939a-7b99-5687-93ae-834e0032f1d5
60
+ //# debugId=1ff4005f-be23-5dcf-9834-dbd7d083b76d
@@ -5,7 +5,7 @@
5
5
  * primitives are shared by native action dispatchers and MCP-specific adapters.
6
6
  */
7
7
 
8
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="2a1e986f-304d-50f6-a405-6afc221bdad5")}catch(e){}}();
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="fde4fea5-94d6-53e2-bfbc-bff71d828c01")}catch(e){}}();
9
9
  import { EXIT_CODE } from "../core/shared/constants.js";
10
10
  import { PmCliError } from "../core/shared/errors.js";
11
11
  import { asRecordClone } from "../core/shared/primitives.js";
@@ -202,6 +202,18 @@ const HOISTED_ACTION_OPTION_KEYS = {
202
202
  update: ["parent", "allowMissingParent", "completedAt"],
203
203
  copy: ["allowDuplicate"],
204
204
  close: ["duplicateOf", "completedAt"],
205
+ comments: ["ifAbsent"],
206
+ notes: ["ifAbsent"],
207
+ learnings: ["ifAbsent"],
208
+ upgrade: [
209
+ "scope",
210
+ "dryRun",
211
+ "cliOnly",
212
+ "packagesOnly",
213
+ "repair",
214
+ "tag",
215
+ "packageName",
216
+ ],
205
217
  // pm-7u9j: the narrow pm_append tool declares `body` top-level; runAppend
206
218
  // reads it from options, while schema/config consume their top-level values
207
219
  // directly in runAction and therefore need no hoisting.
@@ -232,8 +244,7 @@ export function normalizeMcpOptionsArrays(options, action = "") {
232
244
  result[key] = value;
233
245
  continue;
234
246
  }
235
- if (typeof value === "string" &&
236
- scalarToArrayFields.has(key)) {
247
+ if (typeof value === "string" && scalarToArrayFields.has(key)) {
237
248
  result[key] = [value];
238
249
  continue;
239
250
  }
@@ -578,4 +589,4 @@ export function updateManyOptionsFromFlat(options) {
578
589
  };
579
590
  }
580
591
  //# sourceMappingURL=runtime-input.js.map
581
- //# debugId=2a1e986f-304d-50f6-a405-6afc221bdad5
592
+ //# debugId=fde4fea5-94d6-53e2-bfbc-bff71d828c01
@@ -75,7 +75,7 @@ export { migrateItemFilesToFormat } from "../core/store/item-format-migration.js
75
75
  export { type CachedDocumentCandidate, listAllDocumentCandidatesCached, } from "../core/store/item-metadata-cache.js";
76
76
  export { buildItemNotFoundError, createMutationGuardSdk, deleteItem, listAllItemMetadata, listAllItemMetadataLight, locateItem, mutateItem, mutateItemWithHistoryContext, readLocatedItem, } from "../core/store/item-store.js";
77
77
  export { isTerminalPlanMode, shouldCompletePlanOnClose, } from "../core/item/plan-lifecycle.js";
78
- export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, } from "../core/store/paths.js";
78
+ export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, resolveWorkspaceRoot, } from "../core/store/paths.js";
79
79
  export { persistSelectedItemFormat, readSettings, readSettingsWithMetadata, writeSettings, } from "../core/store/settings.js";
80
80
  export { maybeRunFirstUseTelemetryPrompt } from "../core/telemetry/consent.js";
81
81
  export { type TelemetryCommandResolution, type TelemetryResolutionStage, deriveTelemetryCommandResolution, } from "../core/telemetry/observability.js";
@@ -7,7 +7,7 @@
7
7
  * prefer the typed operations exported by the main SDK barrel.
8
8
  */
9
9
 
10
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4be36c51-a9fc-507d-8f13-d764b5668ab9")}catch(e){}}();
10
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d45775e5-6826-521b-80b3-429ed22947d9")}catch(e){}}();
11
11
  export { createCheckpointId, loadMutationCheckpoint, restoreCheckpointItems, writeMutationCheckpoint, } from "../core/checkpoint/mutation-checkpoint.js";
12
12
  export { flattenFlagListValue, resolveFlagValueKind, } from "../core/extensions/flag-value-types.js";
13
13
  export { createUnknownSubcommandError, } from "./agent/subcommand-recovery.js";
@@ -76,10 +76,10 @@ export { migrateItemFilesToFormat } from "../core/store/item-format-migration.js
76
76
  export { listAllDocumentCandidatesCached, } from "../core/store/item-metadata-cache.js";
77
77
  export { buildItemNotFoundError, createMutationGuardSdk, deleteItem, listAllItemMetadata, listAllItemMetadataLight, locateItem, mutateItem, mutateItemWithHistoryContext, readLocatedItem, } from "../core/store/item-store.js";
78
78
  export { isTerminalPlanMode, shouldCompletePlanOnClose, } from "../core/item/plan-lifecycle.js";
79
- export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, } from "../core/store/paths.js";
79
+ export { getHistoryPath, getItemPath, getSettingsPath, resolveImplicitPmRoot, resolvePmRoot, resolveWorkspaceRoot, } from "../core/store/paths.js";
80
80
  export { persistSelectedItemFormat, readSettings, readSettingsWithMetadata, writeSettings, } from "../core/store/settings.js";
81
81
  export { maybeRunFirstUseTelemetryPrompt } from "../core/telemetry/consent.js";
82
82
  export { deriveTelemetryCommandResolution, } from "../core/telemetry/observability.js";
83
83
  export { emitTelemetryErrorEvent, finishTelemetryCommand, startTelemetryCommand, } from "../core/telemetry/runtime.js";
84
84
  //# sourceMappingURL=runtime-primitives.js.map
85
- //# debugId=4be36c51-a9fc-507d-8f13-d764b5668ab9
85
+ //# debugId=d45775e5-6826-521b-80b3-429ed22947d9
@@ -157,11 +157,11 @@ export declare class PmClient {
157
157
  stats<Options extends ReadOptions<StatsCommandOptions> = StatsCommandOptions>(options?: Options): ReadPromise<StatsResult, Options>;
158
158
  /** Discover existing duplicate clusters without mutating tracker state. */
159
159
  duplicates<Options extends ReadOptions<DuplicatesCommandOptions> = DuplicatesCommandOptions>(options?: Options): ReadPromise<DuplicatesResult, Options>;
160
- /** List, add, edit, or delete item comments. */
160
+ /** List or mutate comments, including lock-scoped idempotent appends. */
161
161
  comments<Options extends ReadOptions<CommentsCommandOptions> = CommentsCommandOptions>(id: string, options?: Options): ReadPromise<CommentsResult, Options>;
162
- /** List or append private item notes. */
162
+ /** List or mutate private notes, including lock-scoped idempotent appends. */
163
163
  notes<Options extends ReadOptions<NotesCommandOptions> = NotesCommandOptions>(id: string, options?: Options): ReadPromise<NotesResult, Options>;
164
- /** List or append durable item learnings. */
164
+ /** List or mutate durable learnings, including lock-scoped idempotent appends. */
165
165
  learnings(id: string, options?: LearningsCommandOptions): Promise<LearningsResult>;
166
166
  /** Add, remove, clear, or list linked project files for an item. */
167
167
  files<Options extends ReadOptions<FilesCommandOptions> = FilesCommandOptions>(id: string, options?: Options): ReadPromise<FilesResult, Options>;
@@ -373,11 +373,11 @@ export declare function aggregate<Options extends ReadOptions<AggregateOptions>
373
373
  export declare function stats<Options extends ReadOptions<StatsCommandOptions> = StatsCommandOptions>(options?: Options, clientOptions?: PmClientOptions): ReadPromise<StatsResult, Options>;
374
374
  /** Discover duplicate clusters without constructing a reusable client. */
375
375
  export declare function duplicates<Options extends ReadOptions<DuplicatesCommandOptions> = DuplicatesCommandOptions>(options?: Options, clientOptions?: PmClientOptions): ReadPromise<DuplicatesResult, Options>;
376
- /** List, add, edit, or delete item comments without constructing a reusable client. */
376
+ /** List or mutate comments with optional idempotency without constructing a client. */
377
377
  export declare function comments<Options extends ReadOptions<CommentsCommandOptions> = CommentsCommandOptions>(id: string, options?: Options, clientOptions?: PmClientOptions): ReadPromise<CommentsResult, Options>;
378
- /** List or append private item notes without constructing a reusable client. */
378
+ /** List or mutate private notes with optional idempotency without constructing a client. */
379
379
  export declare function notes<Options extends ReadOptions<NotesCommandOptions> = NotesCommandOptions>(id: string, options?: Options, clientOptions?: PmClientOptions): ReadPromise<NotesResult, Options>;
380
- /** List or append durable item learnings without constructing a reusable client. */
380
+ /** List or mutate durable learnings with optional idempotency without constructing a client. */
381
381
  export declare function learnings(id: string, options?: LearningsCommandOptions, clientOptions?: PmClientOptions): Promise<LearningsResult>;
382
382
  /** Manage linked item files without constructing a reusable client. */
383
383
  export declare function files<Options extends ReadOptions<FilesCommandOptions> = FilesCommandOptions>(id: string, options?: Options, clientOptions?: PmClientOptions): ReadPromise<FilesResult, Options>;
@@ -4,7 +4,7 @@
4
4
  * Defines public SDK APIs and package-author helpers for Runtime.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="72111aa2-52b2-53da-a1c8-07ba53a74944")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b67ba0fe-bbca-57ab-b3be-a4a028f21de4")}catch(e){}}();
8
8
  export { PM_GITIGNORE_END, PM_GITIGNORE_START, ensurePmGitignore, getPmGitignoreBlock, } from "./workspace.js";
9
9
  export { SEARCH_EXTENSION_FLAG_DEFINITIONS } from "./extension-contracts.js";
10
10
  export * from "./cli-contracts/agent-output-contracts.js";
@@ -212,15 +212,15 @@ export class PmClient {
212
212
  duplicates(options = {}) {
213
213
  return this.runTyped("duplicates", { options });
214
214
  }
215
- /** List, add, edit, or delete item comments. */
215
+ /** List or mutate comments, including lock-scoped idempotent appends. */
216
216
  comments(id, options = {}) {
217
217
  return this.runTyped("comments", { id, options });
218
218
  }
219
- /** List or append private item notes. */
219
+ /** List or mutate private notes, including lock-scoped idempotent appends. */
220
220
  notes(id, options = {}) {
221
221
  return this.runTyped("notes", { id, options });
222
222
  }
223
- /** List or append durable item learnings. */
223
+ /** List or mutate durable learnings, including lock-scoped idempotent appends. */
224
224
  learnings(id, options = {}) {
225
225
  return this.runTyped("learnings", { id, options });
226
226
  }
@@ -744,15 +744,15 @@ export function stats(options = {}, clientOptions = {}) {
744
744
  export function duplicates(options = {}, clientOptions = {}) {
745
745
  return new PmClient(clientOptions).duplicates(options);
746
746
  }
747
- /** List, add, edit, or delete item comments without constructing a reusable client. */
747
+ /** List or mutate comments with optional idempotency without constructing a client. */
748
748
  export function comments(id, options = {}, clientOptions = {}) {
749
749
  return new PmClient(clientOptions).comments(id, options);
750
750
  }
751
- /** List or append private item notes without constructing a reusable client. */
751
+ /** List or mutate private notes with optional idempotency without constructing a client. */
752
752
  export function notes(id, options = {}, clientOptions = {}) {
753
753
  return new PmClient(clientOptions).notes(id, options);
754
754
  }
755
- /** List or append durable item learnings without constructing a reusable client. */
755
+ /** List or mutate durable learnings with optional idempotency without constructing a client. */
756
756
  export function learnings(id, options = {}, clientOptions = {}) {
757
757
  return new PmClient(clientOptions).learnings(id, options);
758
758
  }
@@ -1933,4 +1933,4 @@ async function loadWorkspaceExtensionRegistrations(pmRoot, settings, cwd) {
1933
1933
  }
1934
1934
  }
1935
1935
  //# sourceMappingURL=runtime.js.map
1936
- //# debugId=72111aa2-52b2-53da-a1c8-07ba53a74944
1936
+ //# debugId=b67ba0fe-bbca-57ab-b3be-a4a028f21de4
@@ -1,11 +1,17 @@
1
1
  # Noun–Verb CLI Grammar and Compatibility Policy
2
2
 
3
- Tracked by [pm-pbyu](../.agents/pm/decisions/pm-pbyu.toon), implemented through [pm-0z7n](../.agents/pm/features/pm-0z7n.toon), [pm-pfqi](../.agents/pm/tasks/pm-pfqi.toon), [pm-yy8rmx](../.agents/pm/tasks/pm-yy8rmx.toon), and [pm-wt43zj](../.agents/pm/tasks/pm-wt43zj.toon).
3
+ Tracked by [pm-pbyu](../.agents/pm/decisions/pm-pbyu.toon), implemented through [pm-0z7n](../.agents/pm/features/pm-0z7n.toon), [pm-pfqi](../.agents/pm/tasks/pm-pfqi.toon), [pm-yy8rmx](../.agents/pm/tasks/pm-yy8rmx.toon), [pm-wt43zj](../.agents/pm/tasks/pm-wt43zj.toon), [pm-e2bq](../.agents/pm/features/pm-e2bq.toon), and [pm-yql1](../.agents/pm/tasks/pm-yql1.toon).
4
4
 
5
5
  ## Agent Quick Context
6
6
 
7
7
  Use the canonical noun-first form when generating commands. Existing spellings remain executable, but deprecated compatibility aliases are absent from default help and completion discovery and emit one migration hint on stderr. Machine clients can read alias lifecycle and replacement tokens from `pm contracts --full --json`.
8
8
 
9
+ Default `pm --help` stays within the core one-screen budget. Use
10
+ `pm help --all` for every public command or `pm help --all --json` for the same
11
+ surface with per-command visibility/family metadata and the complete alias
12
+ lifecycle table. `--explain` also expands command discovery while adding the
13
+ detailed narrative.
14
+
9
15
  The first completed consolidation is the list family:
10
16
 
11
17
  ```bash
package/docs/COMMANDS.md CHANGED
@@ -178,7 +178,7 @@ As a read-only structured surface, `duplicates` accepts the universal output
178
178
  controls, including `--output-format json`, `--lean`, projection/amount
179
179
  controls, and token accounting, while its default TOON output remains bounded.
180
180
  Tracked by [pm-gh1076](../.agents/pm/issues/pm-gh1076.toon).
181
- Use `pm get <id>` to read a single item by ID — the single-item read primitive used throughout the agent loop. It accepts `--fields <list>` and `--depth brief|standard|deep|full` for token-minimal projections, and `--tree`/`--tree-depth <n>` to include descendants. Standard/deep reads expose a normalized `schedule` facet (`deadline`, `start_at`, `end_at`, `location`, reminders, and events) when scheduling metadata exists. Container-oriented built-ins (Epic, Feature, Milestone, and Plan) plus custom types automatically expose type-agnostic child counts and continuation metadata. Standard depth keeps that rollup counts-only; `--depth deep|full` or an explicit `--fields id,children` request adds the deterministic bounded child sample. Built-in leaf reads avoid a workspace scan unless children are explicitly requested. `pm get <id> --json` returns the `body` inside the `item` object (`.item.body`); see [Full results, totals, and bodies](#full-results-totals-and-bodies). To duplicate an existing item as a starting point, `pm copy <id> --title "New title"` clones it into a fresh id with lifecycle fields reset.
181
+ Use `pm get <id>` to read a single item by ID — the single-item read primitive used throughout the agent loop. It accepts `--fields <list>` and `--depth brief|standard|deep|full` for token-minimal projections, and `--tree`/`--tree-depth <n>` to include descendants. The universal `--output-include` selector can request stored collections directly, for example `pm get <id> --output-include comments,learnings,tests`; the same bare and `item.<field>` grammar works through CLI, SDK, and MCP transports. Standard/deep reads expose a normalized `schedule` facet (`deadline`, `start_at`, `end_at`, `location`, reminders, and events) when scheduling metadata exists. Container-oriented built-ins (Epic, Feature, Milestone, and Plan) plus custom types automatically expose type-agnostic child counts and continuation metadata. Standard depth keeps that rollup counts-only; `--depth deep|full` or an explicit `--fields id,children` request adds the deterministic bounded child sample. Built-in leaf reads avoid a workspace scan unless children are explicitly requested. `pm get <id> --json` returns the `body` inside the `item` object (`.item.body`); see [Full results, totals, and bodies](#full-results-totals-and-bodies). To duplicate an existing item as a starting point, `pm copy <id> --title "New title"` clones it into a fresh id with lifecycle fields reset.
182
182
 
183
183
  When the strongest duplicate match is terminal because the same work recurred,
184
184
  reuse its lineage instead of creating or copying another item:
@@ -735,15 +735,16 @@ explicitly overriding terminal-state or lock conflicts.
735
735
 
736
736
  ```bash
737
737
  pm comments <id> "Implemented command parsing fix."
738
+ pm comments <id> "Implemented command parsing fix." --author agent-a --if-absent
738
739
  printf '%s\n' '## Verification summary' '- Linux pass' '- macOS pass' | pm comments <id> --stdin
739
740
  pm comments <id> --file docs/release-evidence.md
740
741
  pm comments <id> --edit 2 "Corrected: the regression was in the parser, not the renderer."
741
742
  pm comments <id> --delete 3
742
- pm notes <id> --add "Keep renderer changes isolated to TOON output."
743
- pm learnings <id> --add "Use runtime contracts instead of duplicating flag lists."
743
+ pm notes <id> --add "Keep renderer changes isolated to TOON output." --if-absent
744
+ pm learnings <id> --add "Use runtime contracts instead of duplicating flag lists." --if-absent
744
745
  ```
745
746
 
746
- Use comments for progress and evidence, notes for implementation context, and learnings for durable future guidance. `--body` is a hidden compatibility alias for comments `--add`; choose exactly one input source (`[text]`, `--add`/`--body`, `--stdin`, or `--file`) per invocation. To clean up obsolete orchestration notes, `--edit <index>` rewrites the comment at a 1-based index and `--delete <index>` removes it; both record history and honor ownership rules.
747
+ Use comments for progress and evidence, notes for implementation context, and learnings for durable future guidance. All three accept `--text` as a hidden compatibility alias for canonical `--add`; comments also retain `--body`/`--comment`, and notes retain `--note`. Choose exactly one input source (`[text]`, an add alias, `--stdin`, or `--file`) per invocation. Conflicting alias values fail before mutation. For retrying agents, `--if-absent` makes any annotation append idempotent by the resolved author plus exact normalized stored text: the first call returns `changed: true` and `mutation_receipt.changed_count: 1`; an exact retry returns `changed: false`, the existing entry position, and `changed_count: 0` without writing item or history state. Different authors remain distinct, and omitting `--if-absent` deliberately preserves duplicate-appending compatibility. The flag is append-only and is rejected for list, edit, and delete operations. To clean up obsolete orchestration notes, `--edit <index>` rewrites the comment at a 1-based index and `--delete <index>` removes it; both record history and honor ownership rules.
747
748
 
748
749
  ## Linked Artifacts
749
750
 
@@ -7,42 +7,42 @@ Packages add optional `pm` workflows without changing the core CLI. A package ca
7
7
  ```bash
8
8
  pm package init ./my-package
9
9
  pm package init ./my-hook-package --capability hooks
10
- pm install ./my-package --project
10
+ pm package install ./my-package --project
11
11
  pm package doctor --project --detail summary
12
12
  pm package reload --project
13
- pm upgrade --dry-run
13
+ pm package upgrade --dry-run
14
14
  ```
15
15
 
16
- `pm extension ...` remains supported for compatibility and low-level runtime debugging. Related docs: [SDK](SDK.md), [Configuration](CONFIGURATION.md), [Testing](TESTING.md), [Command Reference](COMMANDS.md), [Extension Author Contracts](EXTENSION_AUTHOR_CONTRACTS.md).
16
+ Hidden `pm extension ...`, `pm install ...`, and `pm upgrade ...` aliases remain supported for compatibility. They execute the canonical package handlers, keep stdout machine-compatible, and emit one migration hint on stderr unless the public config key `ux_deprecation_hints` (stored at `ux.deprecation_hints`) is disabled. Related docs: [SDK](SDK.md), [Configuration](CONFIGURATION.md), [Testing](TESTING.md), [Command Reference](COMMANDS.md), [Extension Author Contracts](EXTENSION_AUTHOR_CONTRACTS.md).
17
17
 
18
18
  ## Package Sources
19
19
 
20
- `pm install` accepts local, registry, and GitHub sources:
20
+ `pm package install` accepts local, registry, and GitHub sources:
21
21
 
22
22
  ```bash
23
- pm install ./local-package --project
24
- pm install /absolute/path/to/package --project
25
- pm install ./my-package-1.2.3.tgz --project
26
- pm install npm:./my-package-1.2.3.tar.gz --project
27
- pm install npm:@scope/package --project
28
- pm install npm:package@1.2.3 --project
29
- pm install https://github.com/org/repo --project
30
- pm install --github org/repo/path --ref main --project
23
+ pm package install ./local-package --project
24
+ pm package install /absolute/path/to/package --project
25
+ pm package install ./my-package-1.2.3.tgz --project
26
+ pm package install npm:./my-package-1.2.3.tar.gz --project
27
+ pm package install npm:@scope/package --project
28
+ pm package install npm:package@1.2.3 --project
29
+ pm package install https://github.com/org/repo --project
30
+ pm package install --github org/repo/path --ref main --project
31
31
  ```
32
32
 
33
33
  Bundled first-party packages live under `packages/pm-*`:
34
34
 
35
35
  ```bash
36
36
  pm package catalog --project
37
- pm install all --project
38
- pm install calendar --project
39
- pm install search-advanced --project
40
- pm install kanban --project
37
+ pm package install all --project
38
+ pm package install calendar --project
39
+ pm package install search-advanced --project
40
+ pm package install kanban --project
41
41
  ```
42
42
 
43
- `pm install '*'`, `pm install all`, and shell-expanded `pm install *` are normalized to the same bundled install-all request. First-party package aliases come from each package manifest, with a fallback derived from the `packages/pm-*` directory name. A bare bundled alias that also names an installed npm package reports both explicit choices in `source_resolution`; see [Extension Lifecycle Contracts](EXTENSION_LIFECYCLE.md).
43
+ `pm package install '*'` and `pm package install all` are normalized to the same bundled install-all request. First-party package aliases come from each package manifest, with a fallback derived from the `packages/pm-*` directory name. A bare bundled alias that also names an installed npm package reports both explicit choices in `source_resolution`; see [Extension Lifecycle Contracts](EXTENSION_LIFECYCLE.md).
44
44
 
45
- External registry packages are installed by exact package name. If `npm:<name>` returns a registry 404, JSON error output includes `fallback_candidates` and `next_best_command`; unpublished first-party packages fall back to `pm install --project github.com/unbraind/<name>`. Install results include package-owned `command_paths`, `action_paths`, `contributions`, `command_discovery`, and a light `verification` block covering the target tracker, activation status, registered commands/actions/item types, and health verdict. Agents should consume those fields instead of guessing from the package name or immediately spending another invocation on doctor. A successful activation persists the versioned contribution inventory in `.managed-extensions.json`; subsequent discovery can enumerate command handlers, hooks, parser/renderer targets, schema names, and the other registered surfaces without importing the package module. A failed runtime activation returns `ok: false`, `activated: false`, a non-zero CLI exit, and actionable diagnostics; missing SDK resolution adds an explicit dependency recovery step. Local installs are containment-safe when the extension destination is nested inside the source checkout: pm stages the package outside the source and prunes the destination, `.agents`, `node_modules`, and install-backup directories before copying, so reinstalling cannot recursively copy tracker history, host dependencies, or prior backups.
45
+ External registry packages are installed by exact package name. If `npm:<name>` returns a registry 404, JSON error output includes `fallback_candidates` and `next_best_command`; unpublished first-party packages fall back to `pm package install --project github.com/unbraind/<name>`. Install results include package-owned `command_paths`, `action_paths`, `contributions`, `command_discovery`, and a light `verification` block covering the target tracker, activation status, registered commands/actions/item types, and health verdict. Agents should consume those fields instead of guessing from the package name or immediately spending another invocation on doctor. A successful activation persists the versioned contribution inventory in `.managed-extensions.json`; subsequent discovery can enumerate command handlers, hooks, parser/renderer targets, schema names, and the other registered surfaces without importing the package module. A failed runtime activation returns `ok: false`, `activated: false`, a non-zero CLI exit, and actionable diagnostics; missing SDK resolution adds an explicit dependency recovery step. Local installs are containment-safe when the extension destination is nested inside the source checkout: pm stages the package outside the source and prunes the destination, `.agents`, `node_modules`, and install-backup directories before copying, so reinstalling cannot recursively copy tracker history, host dependencies, or prior backups.
46
46
  Local `.tgz` and `.tar.gz` npm archives are inspected and extracted in an isolated temporary directory without invoking a shell. Archives must contain one `package/package.json` root, regular files/directories only, and bounded entry and expanded-byte totals. Absolute paths, traversal, alternate roots, links, device entries, oversized entries, and decompression-ratio abuse fail before installation. The managed source remains the original archive path, so reload and upgrade provenance do not point at a temporary extraction directory.
47
47
  Registry dependency names and versions are parsed as npm package specs before the install subprocess starts. Leading-option names and shell control syntax are rejected. npm reads those validated dependencies from an isolated runtime-only manifest; no caller-controlled spec is forwarded through the Windows command shell, and the fixed invocation still ends option parsing with `--`. Runtime verification then activates a temporary snapshot of the complete installed extension directory, so an upgrade cannot silently reuse stale transitive ESM dependencies from the current process. Successful install details expose `module_graph_verification: "fresh_snapshot"` for this check.
48
48
  pm-owned npm subprocesses clear any inherited, case-insensitive `npm_config_allow_scripts` value while retaining registry, auth, proxy, and executable-path environment; `--ignore-scripts` remains authoritative. Tracked by [pm-gh1072](../.agents/pm/issues/pm-gh1072.toon).
@@ -50,8 +50,8 @@ An explicit `--pm-path` scopes project installs to that tracker root, including
50
50
 
51
51
  ```bash
52
52
  npm search "pm-cli pm-package"
53
- pm install npm:pm-changelog --project
54
- pm install npm:pm-github --project
53
+ pm package install npm:pm-changelog --project
54
+ pm package install npm:pm-github --project
55
55
  pm package doctor --project --detail deep --trace
56
56
  pm github validate --repo owner/repo
57
57
  ```
@@ -91,7 +91,7 @@ Package roots declare resources in `package.json` under `pm`:
91
91
  ```
92
92
 
93
93
  Installation activates `pm.extensions`. `pm.docs`, `pm.examples`, `pm.assets`, and `pm.prompts` are catalog metadata (metadata-only — they are discovered and surfaced in the catalog but not executed). Declare agent-facing prompt/slash-command markdown under `pm.prompts` and non-code assets (images, skills, fixtures) under `pm.assets`; their conventional roots are `prompts/` (also `.agents/pm/prompts/`) and `assets/` (also `.agents/pm/assets/`).
94
- `pm package init` and its compatibility spelling `pm extension init` emit the same publishable root-extension artifact (`"extensions": ["."]`): package metadata, a typed `index.ts`, a colocated `node:test` suite, a strict type-check-only `tsconfig.json`, and `typecheck`/`test` scripts. Both results report the canonical `package_name` and exact `invocation_command`; an already prefixed target such as `pm-my-workflow` stays `pm-my-workflow` instead of becoming `pm-pm-my-workflow`. The manifest `entry` points at `./index.ts` itself (ADR [pm-2c28](../.agents/pm/decisions/pm-2c28.toon) / [pm-m1uz](../.agents/pm/decisions/pm-m1uz.toon)). pm loads that `.ts` entry directly via Node's native type stripping (Node >=22.18), so there is no build step — run `npm install` (for the peer SDK and type-checking) before `pm install`. The generated README shows how to author exported command/hook definitions with the SDK [define\* builders](../.agents/pm/decisions/pm-3mph.toon). `--capability` selects one of ten starters — one per SDK registration surface (`commands`, `hooks`, `search`, `importers`, `schema`, `profile`, `renderers`, `parser`, `preflight`, `services`) each keeping a runnable starter command and adding the surface's registration plus a colocated `node:test` suite built on the matching SDK `assertRegistered*`/`runRegistered*ForTest` helpers. The option is repeatable for shell and config composition: repeating the same capability is idempotent, while combining distinct starter shapes fails with a usage error that asks the author to select one explicit scaffold capability. The full per-capability matrix (what each starter registers, which starters also declare `schema` because flag metadata is schema-governed, and why `schema`/`profile` omit `activation.commands` so their global contributions activate conservatively for every command) lives in [SDK.md — Minimal Command Extension](./SDK.md#minimal-command-extension). Starter manifests use the same least-privilege policy metadata as pure first-party command packages: `trusted: true`, `sandbox_profile: "strict"`, and explicit `false` permissions for `fs_read`, `fs_write`, `network`, `env_read`, `env_write`, and `process_spawn`. Declarative starters import `manifest.json` in their generated test and call `assertExtensionManifestMatchesBlueprint`, so capability drift fails locally before publication. Larger packages may point at nested extension directories after declaring runtime dependencies, relaxing only the permissions they actually need, and validating with `pm package doctor`, which additionally emits the advisory `extension_schema_narrow_activation` warning when a package registers custom item types/fields yet declares narrow `activation.commands` (the schema footgun above), recommending the field be dropped so the type stays globally available.
94
+ `pm package init` and its compatibility spelling `pm extension init` emit the same publishable root-extension artifact (`"extensions": ["."]`): package metadata, a typed `index.ts`, a colocated `node:test` suite, a strict type-check-only `tsconfig.json`, and `typecheck`/`test` scripts. Both results report the canonical `package_name` and exact `invocation_command`; an already prefixed target such as `pm-my-workflow` stays `pm-my-workflow` instead of becoming `pm-pm-my-workflow`. The manifest `entry` points at `./index.ts` itself (ADR [pm-2c28](../.agents/pm/decisions/pm-2c28.toon) / [pm-m1uz](../.agents/pm/decisions/pm-m1uz.toon)). pm loads that `.ts` entry directly via Node's native type stripping (Node >=22.18), so there is no build step — run `npm install` (for the peer SDK and type-checking) before `pm package install`. The generated README shows how to author exported command/hook definitions with the SDK [define\* builders](../.agents/pm/decisions/pm-3mph.toon). `--capability` selects one of ten scaffold starters (`commands`, `hooks`, `search`, `importers`, `schema`, `profile`, `renderers`, `parser`, `preflight`, `services`), each keeping a runnable starter command and adding the selected registration pattern plus a colocated `node:test` suite built on the matching SDK `assertRegistered*`/`runRegistered*ForTest` helpers. These are authoring selectors, not a one-to-one manifest-capability vocabulary: the `profile` starter registers a profile but declares the supported `schema` manifest capability because `api.registerProfile` is schema-governed. The option is repeatable for shell and config composition: repeating the same capability is idempotent, while combining distinct starter shapes fails with a usage error that asks the author to select one explicit scaffold capability. The full per-capability matrix (what each starter registers, which starters also declare `schema` because flag metadata is schema-governed, and why `schema`/`profile` omit `activation.commands` so their global contributions activate conservatively for every command) lives in [SDK.md — Minimal Command Extension](./SDK.md#minimal-command-extension). Starter manifests use the same least-privilege policy metadata as pure first-party command packages: `trusted: true`, `sandbox_profile: "strict"`, and explicit `false` permissions for `fs_read`, `fs_write`, `network`, `env_read`, `env_write`, and `process_spawn`. Declarative starters import `manifest.json` in their generated test and call `assertExtensionManifestMatchesBlueprint`, so capability drift fails locally before publication. Larger packages may point at nested extension directories after declaring runtime dependencies, relaxing only the permissions they actually need, and validating with `pm package doctor`, which additionally emits the advisory `extension_schema_narrow_activation` warning when a package registers custom item types/fields yet declares narrow `activation.commands` (the schema footgun above), recommending the field be dropped so the type stays globally available.
95
95
  Package tests can pair `readPmPackageManifest(packageRoot)` with
96
96
  `assertPackageManifest(manifest, { resources: ... })` from
97
97
  `@unbrained/pm-cli/sdk` to prove aliases and resource paths without duplicating
@@ -202,11 +202,11 @@ Use [extension-manifest.schema.json](schemas/extension-manifest.schema.json) as
202
202
  - An empty-string or non-string `pm_min_version`/`pm_max_version` makes the whole manifest malformed (`extension_manifest_invalid:<layer>:<name>`). Omit the field instead of leaving it blank.
203
203
  - Optional `engines.pm` and `engines.node` metadata is accepted for tooling, but `pm_min_version`/`pm_max_version` are the loader-enforced compatibility fields.
204
204
  - Declare only capabilities the extension actually uses. Declaring a capability it never registers against is over-broad: `pm package doctor` emits an advisory `extension_capability_unused:<layer>:<name>:<capability>` warning (never blocking) so you can trim the manifest, while the inverse — registering a surface whose capability is undeclared — is the blocking `extension_capability_missing` activation failure. Catch over-declaration earlier with the `assertExtensionCapabilityUsage` SDK testing helper.
205
- - `contributions` is the versioned, serializable surface inventory. `schema_version: 1` supports command definitions/handlers/overrides, hook phases, flag/parser targets, item types and fields, relationship kinds, migrations, profiles, importers/exporters, search/vector providers, service/renderer targets, renderer command ownership, and the preflight count. `pm install` derives and persists this block mechanically from the real activation result; authors may also declare it in `manifest.json` for build-time/static discovery.
205
+ - `contributions` is the versioned, serializable surface inventory. `schema_version: 1` supports command definitions/handlers/overrides, hook phases, flag/parser targets, item types and fields, relationship kinds, migrations, profiles, importers/exporters, search/vector providers, service/renderer targets, renderer command ownership, and the preflight count. `pm package install` derives and persists this block mechanically from the real activation result; authors may also declare it in `manifest.json` for build-time/static discovery.
206
206
  - `activation.commands` is an optional array of the command paths on which the extension may activate (e.g. `["hello", "tickets import"]`). An explicit list is authoritative for every capability, including hooks and parser/preflight/renderer packages: when no declared path matches, pm does not import the module. Omit it and pm first uses the static contribution inventory, then falls back to conservative capability heuristics for legacy packages whose contributions are unknown.
207
207
  - Unknown capabilities emit deterministic warnings; legacy aliases such as `migration` and `validation` are normalized to `schema` with warnings.
208
208
 
209
- Supported capabilities:
209
+ Supported manifest capabilities (the `profile` scaffold selector emits a profile registration under `schema`; it is not a manifest capability):
210
210
 
211
211
  - `commands`
212
212
  - `parser`
@@ -293,9 +293,11 @@ Doctor JSON also includes `triage.collision_plan` with grouped surfaces, ranked
293
293
  ## Runtime APIs
294
294
 
295
295
  Use the public SDK barrel. Do not deep-import from `src/core` or `dist/core`.
296
+
296
297
  ```ts
297
298
  import { defineExtension } from "@unbrained/pm-cli/sdk";
298
299
  ```
300
+
299
301
  Common APIs:
300
302
 
301
303
  - `api.extension` is a read-only identity (`name`, `layer`, `version`, `capabilities`, `pm_min_version?`, `pm_max_version?`, `source_package?`) for self-identifying logs and version gating without re-reading the manifest.
@@ -383,14 +385,14 @@ Compatibility equivalents remain available through `pm extension ...` for existi
383
385
 
384
386
  ## Upgrade Workflow
385
387
 
386
- `pm upgrade` is the package-first update entrypoint:
388
+ `pm package upgrade` is the package-first update entrypoint:
387
389
 
388
390
  ```bash
389
- pm upgrade --dry-run
390
- pm upgrade
391
- pm upgrade --packages-only
392
- pm upgrade todos --dry-run
393
- pm upgrade --cli-only --repair
391
+ pm package upgrade --dry-run
392
+ pm package upgrade
393
+ pm package upgrade --packages-only
394
+ pm package upgrade todos --dry-run
395
+ pm package upgrade --cli-only --repair
394
396
  ```
395
397
 
396
398
  CLI/SDK upgrades use `npm install -g @unbrained/pm-cli@<tag>`. Managed package upgrades reuse the source recorded at install time, including registry, GitHub, local, and first-party package sources.
@@ -401,7 +403,7 @@ Use non-interactive commands with explicit project scope:
401
403
 
402
404
  ```bash
403
405
  pm init --defaults --author codex-agent
404
- pm install '*' --project
406
+ pm package install '*' --project
405
407
  pm package doctor --project --detail summary --json
406
408
  pm contracts --flags-only --json
407
409
  pm health --check-only --json
@@ -421,8 +423,7 @@ import { createExtensionTestHarness } from "@unbrained/pm-cli/sdk/testing";
421
423
  import { activateExtensionForTest } from "@unbrained/pm-cli/sdk/testing";
422
424
  ```
423
425
 
424
- Runtime modules use static SDK imports; installed copies receive a host SDK link. Use `createPmCliExpectedError(message, { exitCode, context })` for expected user/action failures from package commands. It creates an `Error` named `PmCliError` with a structural `exitCode`, so separately installed package code still gets expected-error handling and Sentry filtering.
425
- Commands that need to render a structured gate report and still fail CI may instead return an object with `exit_code` from `1` through `255`; optional string `code` and `remediation` fields are preserved by the host. The result is rendered normally, and the CLI exits with the declared status. Thrown plain objects also preserve bounded `code` and `remediation` fields in the host error contract.
426
+ Runtime modules use static SDK imports; installed copies receive a host SDK link. Use `createPmCliExpectedError(message, { exitCode, context })` for expected user/action failures from package commands. It creates an `Error` named `PmCliError` with a structural `exitCode`, so separately installed package code still gets expected-error handling and Sentry filtering. Commands that need to render a structured gate report and still fail CI may instead return an object with `exit_code` from `1` through `255`; optional string `code` and `remediation` fields are preserved by the host. The result is rendered normally, and the CLI exits with the declared status. Thrown plain objects also preserve bounded `code` and `remediation` fields in the host error contract.
426
427
  Prefer the `define*` builders for exported registration definitions (`defineCommand`, `defineFlag`, `defineSearchProvider`, `defineAfterCommandHook`, and the matching override/import/export/hook helpers; see ADR [pm-3mph](../.agents/pm/decisions/pm-3mph.toon)). They are zero-cost identity functions that preserve object literal types and contextually type function parameters before the definitions reach `api.register*`; runtime validation remains in the loader, and behavior validation remains in `sdk/testing`.
427
428
  Packages that extend core list or search behavior should import `LIST_FILTER_EXTENSION_FLAG_DEFINITIONS`, `SEARCH_EXTENSION_FLAG_DEFINITIONS`, or `toExtensionFlagDefinitions` from `@unbrained/pm-cli/sdk/authoring` instead of copying CLI option tables. For example: `api.registerFlags("my search", SEARCH_EXTENSION_FLAG_DEFINITIONS)`.
428
429
  The adapter expands aliases into registration-ready definitions and preserves string/boolean behavior, list accumulation, repeatability, requiredness, descriptions, and value names from the canonical CLI contracts. Use `toExtensionFlagDefinitions` with another exported CLI flag contract for a narrower baseline.
@@ -10,7 +10,9 @@ and the cache/schema surface are tracked by
10
10
  Streamable HTTP, remote authorization, and the deprecation ratchet are tracked
11
11
  by [pm-v7e337](../.agents/pm/features/pm-v7e337.toon),
12
12
  [pm-3zh9s4](../.agents/pm/features/pm-3zh9s4.toon), and
13
- [pm-vzcisw](../.agents/pm/chores/pm-vzcisw.toon).
13
+ [pm-vzcisw](../.agents/pm/chores/pm-vzcisw.toon). Skills and Apps are tracked
14
+ by [pm-8nzivt](../.agents/pm/features/pm-8nzivt.toon) and
15
+ [pm-pznhee](../.agents/pm/features/pm-pznhee.toon).
14
16
 
15
17
  Status: accepted. MCP `2026-07-28` is pm's canonical protocol revision.
16
18
 
@@ -127,6 +129,25 @@ explicit `ttlMs` and `cacheScope`. Tool schemas are validated as bounded JSON
127
129
  Schema 2020-12 documents before advertisement. Tool and resource data stay
128
130
  private; public metadata lists may be cached for their advertised lifetime.
129
131
 
132
+ ## Skills and Apps extensions
133
+
134
+ Discovery advertises the stable `io.modelcontextprotocol/ui` MCP Apps
135
+ extension and the revision-pinned draft `io.modelcontextprotocol/skills`
136
+ extension. They remain optional and request-local. Apps require the stable
137
+ `2026-01-26` MIME capability; Skills require the exact SEP-2640 commit and
138
+ explicit directory-read support for bulk reads. An incompatible Apps
139
+ declaration is treated as absent by `tools/list` and `resources/list`, so those
140
+ discovery methods degrade to the non-UI surface; direct `ui://` reads remain
141
+ strict and return the allocated missing-capability error. Skills methods fail
142
+ closed on an incompatible draft declaration because their entire method family
143
+ depends on that exact negotiated revision.
144
+
145
+ The public SDK owns skill parsing, digesting, pagination, origin provenance,
146
+ resource bounds, App contracts, tool metadata, sandbox policy, and accessible
147
+ self-contained HTML. The server only applies negotiation and dispatch. See
148
+ [MCP Skills and Apps](MCP_SKILLS_AND_APPS.md) for the wire examples and trust
149
+ model.
150
+
130
151
  ## Public SDK
131
152
 
132
153
  Use `PM_MCP_PROTOCOL_VERSION`, `resolveMcpRequestContext()`,
@@ -135,4 +156,5 @@ Use `PM_MCP_PROTOCOL_VERSION`, `resolveMcpRequestContext()`,
135
156
  `validateMcpHttpRequestHeaders()`, `buildMcpProtectedResourceMetadata()`, and
136
157
  the issuer/trace authorization helpers from `@unbrained/pm-cli/sdk`. See
137
158
  [MCP interaction and task SDK](SDK_MCP_INTERACTIONS.md) and
138
- [remote transport, authorization, and migration](MCP_REMOTE_TRANSPORT_SECURITY.md).
159
+ [remote transport, authorization, and migration](MCP_REMOTE_TRANSPORT_SECURITY.md),
160
+ plus [MCP Skills and Apps](MCP_SKILLS_AND_APPS.md).
@@ -18,13 +18,13 @@ evidence or an explicit open obligation.
18
18
  | Official `io.modelcontextprotocol/tasks` extension | [pm-rzs24j](../.agents/pm/features/pm-rzs24j.toon) | Implemented for eligible tool calls, durable lifecycle, and stdio methods; notifications remain with subscriptions owner | `tests/unit/sdk/mcp/tasks.spec.ts`, `tests/integration/mcp-stateless-protocol.spec.ts` |
19
19
  | Cacheable list/read results, deterministic tools, JSON Schema 2020-12, any JSON structured content | [pm-hv1x1x](../.agents/pm/features/pm-hv1x1x.toon) | Implemented for current pm tool/resource/prompt surfaces | SDK schema/cache tests and direct modern server surface suite |
20
20
  | Issuer-bound authorization, client metadata documents, consent, headers, OpenTelemetry | [pm-3zh9s4](../.agents/pm/features/pm-3zh9s4.toon) | Implemented locally; deployment verifier integration remains host-owned | authorization SDK adversarial tests, real HTTP bearer suite, and threat model |
21
- | Core extension negotiation and official extension fallback | [pm-pznhee](../.agents/pm/features/pm-pznhee.toon) | Open | owner acceptance criteria and release matrix |
22
- | Skills over MCP | [pm-8nzivt](../.agents/pm/features/pm-8nzivt.toon) | Open | owner acceptance criteria define capability and token-budget proof |
21
+ | Stable MCP Apps negotiation, tool/resource metadata, fallback, sandboxing, and accessible views | [pm-pznhee](../.agents/pm/features/pm-pznhee.toon) | Implemented in the public SDK and stateless server; packed/published proof follows merge | `tests/unit/sdk/mcp/apps.spec.ts`, `tests/integration/mcp-stateless-protocol.spec.ts` |
22
+ | Draft Skills over MCP list/get/read, compatibility, provenance, digests, bounds, and pagination | [pm-8nzivt](../.agents/pm/features/pm-8nzivt.toon) | Implemented against exact SEP-2640 draft revision; packed/published proof follows merge | `tests/unit/sdk/mcp/skills.spec.ts`, `tests/integration/mcp-stateless-protocol.spec.ts` |
23
23
  | Deprecated Roots, Sampling, Logging, HTTP+SSE, `includeContext`, dynamic registration | [pm-vzcisw](../.agents/pm/chores/pm-vzcisw.toon) | Canonical source ratcheted; bounded stdio adapter and dated migration policy remain | generated inventory, negative controls, adapter tests, and migration guide |
24
24
  | Official schema, real stdio/HTTP, packed/published, npx/bunx, negative controls | [pm-55yf1t](../.agents/pm/tasks/pm-55yf1t.toon) | Foundation implemented; remains open until every owner above closes | SDK/server suites, plugin smokes, published-release verifier |
25
25
 
26
- The programme gate remains intentionally incomplete while any row says `Open`
27
- or while local-only rows lack their packed and published evidence. Provider
26
+ The programme gate remains intentionally incomplete while local-only rows
27
+ lack their packed and published evidence. Provider
28
28
  silence, a successful legacy initialize, or source-only unit coverage cannot
29
29
  promote such a row. Completion requires the owner's positive and negative
30
30
  tests plus exact packed and published consumer proof.