@unbrained/pm-cli 2026.8.29 → 2026.8.31

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 (136) hide show
  1. package/.agents/skills/HARNESS_COMPATIBILITY.md +1 -1
  2. package/.agents/skills/README.md +1 -1
  3. package/.agents/skills/pm-developer/SKILL.md +1 -1
  4. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +2 -2
  5. package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +1 -1
  6. package/.agents/skills/pm-developer/references/TOKEN_BUDGETS.md +1 -1
  7. package/.agents/skills/pm-extensions/SKILL.md +2 -2
  8. package/.agents/skills/pm-extensions/references/AUTHORING.md +1 -1
  9. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +1 -1
  10. package/.agents/skills/pm-sdk/SKILL.md +1 -1
  11. package/.agents/skills/pm-user/SKILL.md +2 -2
  12. package/.agents/skills/pm-user/references/WORKFLOWS.md +2 -2
  13. package/.claude-plugin/marketplace.json +2 -2
  14. package/AGENTS.md +1 -1
  15. package/CHANGELOG.md +24 -0
  16. package/dist/cli/register-list-query.js +32 -17
  17. package/dist/cli/register-operations.d.ts +2 -0
  18. package/dist/cli/register-operations.js +20 -9
  19. package/dist/cli-bundle/bundle-manifest.json +137 -137
  20. package/dist/cli-bundle/chunks/chunk-2XVV45NJ.js +35 -0
  21. package/dist/cli-bundle/chunks/{chunk-N6OR6FAR.js → chunk-3FCSFWZT.js} +12 -12
  22. package/dist/cli-bundle/chunks/{chunk-WS2GJQVG.js → chunk-52JXYSDW.js} +2 -2
  23. package/dist/cli-bundle/chunks/{chunk-TGNAA66W.js → chunk-5DH5XCJL.js} +2 -2
  24. package/dist/cli-bundle/chunks/{chunk-2UETTHY6.js → chunk-IEFJ3ZEB.js} +29 -29
  25. package/dist/cli-bundle/chunks/{chunk-MTTKAUBX.js → chunk-JIFYOJF7.js} +2 -2
  26. package/dist/cli-bundle/chunks/{chunk-3TEF3HM5.js → chunk-MWIN6OH2.js} +2 -2
  27. package/dist/cli-bundle/chunks/{chunk-GNWPTEBW.js → chunk-NW6LV3TU.js} +64 -64
  28. package/dist/cli-bundle/chunks/{chunk-7SKMLSMX.js → chunk-OUGDA7NR.js} +2 -2
  29. package/dist/cli-bundle/chunks/{chunk-2MKLQL2E.js → chunk-QZCIBZR3.js} +2 -2
  30. package/dist/cli-bundle/chunks/{chunk-CMIEDWAY.js → chunk-SXMHPK4V.js} +41 -41
  31. package/dist/cli-bundle/chunks/{register-list-query-OMKJ5ONN.js → register-list-query-7C7DKZ2U.js} +11 -11
  32. package/dist/cli-bundle/chunks/{register-mutation-QBSNCOY3.js → register-mutation-OI4BJLUX.js} +2 -2
  33. package/dist/cli-bundle/chunks/register-operations-IIMA5OKO.js +2 -0
  34. package/dist/cli-bundle/chunks/{register-setup-GLQ5SYV3.js → register-setup-52H36QCB.js} +2 -2
  35. package/dist/cli-bundle/focused-chunks/{chunk-HVQ22RC4.js → chunk-2FEZ5SKM.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/{chunk-Y3JJXRVK.js → chunk-4O4CJAR6.js} +5 -5
  37. package/dist/cli-bundle/focused-chunks/{chunk-RKOKG43G.js → chunk-APN4QN6R.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/{chunk-LYFWQMVC.js → chunk-BEVHCEWG.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/{chunk-3UMBF26I.js → chunk-BMD42PUG.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-XXOWRJZ5.js → chunk-BPWJ4QM5.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/{chunk-G6PATS5E.js → chunk-EUTABA4M.js} +15 -15
  42. package/dist/cli-bundle/focused-chunks/{chunk-73EDXGYE.js → chunk-FOMZ6NG5.js} +2 -2
  43. package/dist/cli-bundle/focused-chunks/chunk-JCOOAUHK.js +51 -0
  44. package/dist/cli-bundle/focused-chunks/chunk-JEFKLWMM.js +2 -0
  45. package/dist/cli-bundle/focused-chunks/{chunk-JZYPPMXF.js → chunk-KB5OFSFD.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/{chunk-AD6ULRAF.js → chunk-QDFJIRKN.js} +4 -4
  47. package/dist/cli-bundle/focused-chunks/{chunk-THEPQMLX.js → chunk-SVXJYD6G.js} +2 -2
  48. package/dist/cli-bundle/focused-chunks/{chunk-3AVAWVZA.js → chunk-UN34D63M.js} +2 -2
  49. package/dist/cli-bundle/focused-chunks/{chunk-TDK3OCX3.js → chunk-VJ7EFMFL.js} +2 -2
  50. package/dist/cli-bundle/main.js +2 -2
  51. package/dist/cli-bundle/sdk-authoring.js +1 -1
  52. package/dist/cli-bundle/sdk-contracts.js +1 -1
  53. package/dist/cli-bundle/sdk-core.js +29 -29
  54. package/dist/cli-bundle/sdk-governance.js +1 -1
  55. package/dist/cli-bundle/sdk-graph.js +1 -1
  56. package/dist/cli-bundle/sdk-merge.js +33 -33
  57. package/dist/cli-bundle/sdk-query.js +1 -1
  58. package/dist/cli-bundle/sdk-runtime.js +1 -1
  59. package/dist/cli-bundle/sdk-testing.js +1 -1
  60. package/dist/cli-bundle/sdk.js +9 -9
  61. package/dist/core/schema/runtime-schema.d.ts +4 -0
  62. package/dist/core/schema/runtime-schema.js +60 -48
  63. package/dist/core/schema/status-defs-file.js +5 -2
  64. package/dist/mcp/legacy-adapter.d.ts +11 -2
  65. package/dist/mcp/legacy-adapter.js +26 -12
  66. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  67. package/dist/sdk/cli-contracts/flag-contracts.js +6 -2
  68. package/dist/sdk/cli-contracts/grammar-contracts.d.ts +1 -1
  69. package/dist/sdk/cli-contracts/grammar-contracts.js +12 -2
  70. package/dist/sdk/cli-contracts/runtime-contracts.js +3 -2
  71. package/dist/sdk/cli-contracts/tool-schema.js +11 -3
  72. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
  73. package/dist/sdk/governance/health.js +17 -6
  74. package/dist/sdk/governance/status-role-diagnostics.d.ts +27 -0
  75. package/dist/sdk/governance/status-role-diagnostics.js +36 -0
  76. package/dist/sdk/governance/validate-normalization.d.ts +6 -0
  77. package/dist/sdk/governance/validate-normalization.js +37 -0
  78. package/dist/sdk/governance/validate.d.ts +1 -1
  79. package/dist/sdk/governance/validate.js +20 -35
  80. package/dist/sdk/governance/workspace-position.d.ts +69 -0
  81. package/dist/sdk/governance/workspace-position.js +164 -0
  82. package/dist/sdk/governance.d.ts +2 -0
  83. package/dist/sdk/governance.js +4 -2
  84. package/dist/sdk/index.d.ts +1 -1
  85. package/dist/sdk/index.js +3 -3
  86. package/dist/sdk/mcp/protocol.d.ts +10 -2
  87. package/dist/sdk/mcp/protocol.js +15 -4
  88. package/dist/sdk/query/context.js +11 -14
  89. package/dist/sdk/query/list.d.ts +2 -0
  90. package/dist/sdk/query/list.js +33 -12
  91. package/dist/sdk/runtime-extended-actions.js +8 -4
  92. package/dist/sdk/schema.js +12 -2
  93. package/dist/sdk/test/execution.d.ts +15 -0
  94. package/dist/sdk/test/execution.js +35 -27
  95. package/docs/AGENT_GUIDE.md +1 -1
  96. package/docs/AGENT_PROVENANCE_ADR.md +1 -1
  97. package/docs/AGENT_RUNTIME_PRIMITIVES.md +2 -2
  98. package/docs/CLAUDE_CODE_PLUGIN.md +3 -3
  99. package/docs/COMMANDS.md +12 -12
  100. package/docs/CONFIGURATION.md +1 -1
  101. package/docs/DEFECT_RECURRENCE.md +2 -0
  102. package/docs/MCP_2026_07_28.md +28 -8
  103. package/docs/MCP_2026_07_28_CONFORMANCE.md +1 -0
  104. package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +4 -2
  105. package/docs/ONBOARDING.md +1 -1
  106. package/docs/README.md +2 -1
  107. package/docs/READ_OUTPUT_CONTRACTS.md +1 -1
  108. package/docs/RECURRENCE_RECOVERY_CONTRACTS.md +1 -1
  109. package/docs/SDK.md +3 -3
  110. package/docs/TESTING.md +23 -14
  111. package/docs/WORKSPACE_POSITION_AND_LIFECYCLE.md +113 -0
  112. package/docs/examples/policy-restricted-extension/README.md +2 -2
  113. package/docs/examples/starter-extension/README.md +1 -1
  114. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
  115. package/marketplace.json +2 -2
  116. package/package.json +4 -4
  117. package/packages/pm-beads/package.json +1 -1
  118. package/packages/pm-calendar/package.json +1 -1
  119. package/packages/pm-command-kit/package.json +1 -1
  120. package/packages/pm-digital-twin/package.json +1 -1
  121. package/packages/pm-governance-audit/package.json +1 -1
  122. package/packages/pm-guide-shell/package.json +1 -1
  123. package/packages/pm-kanban/package.json +1 -1
  124. package/packages/pm-lifecycle-hooks/package.json +1 -1
  125. package/packages/pm-linked-test-adapters/package.json +1 -1
  126. package/packages/pm-search-advanced/package.json +1 -1
  127. package/packages/pm-templates/package.json +1 -1
  128. package/packages/pm-todos/package.json +1 -1
  129. package/packages/pm-vcs/package.json +1 -1
  130. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  131. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  132. package/sdk/public-surface.json +171 -10
  133. package/dist/cli-bundle/chunks/chunk-7X6OZEIV.js +0 -34
  134. package/dist/cli-bundle/chunks/register-operations-UC77FQZC.js +0 -2
  135. package/dist/cli-bundle/focused-chunks/chunk-AXZ5AJAF.js +0 -50
  136. package/dist/cli-bundle/focused-chunks/chunk-LLNTHF5X.js +0 -2
@@ -4,7 +4,7 @@
4
4
  * Implements the pm list 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]="93e8c187-e198-50fc-bf2c-7dae2ea42219")}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]="ccdb7d16-4f38-58d4-a19d-4ab1516cb1d7")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
9
  import { getActiveExtensionRegistrations, hasActiveOnReadHooks, } from "../../core/extensions/index.js";
10
10
  import { toItemRecord } from "../../core/item/item-record.js";
@@ -978,20 +978,40 @@ function resolveListOrderingOptions(options) {
978
978
  }
979
979
  function resolveListStatusSelection(status, options, statusRegistry) {
980
980
  const explicitStatus = resolveStatusFilter(options.status, statusRegistry);
981
- const resolvedStatus = explicitStatus ?? resolveStatusFilter(status, statusRegistry);
981
+ let lifecycleStatus;
982
+ if (options.lifecycleBucket === "in_progress") {
983
+ lifecycleStatus = [statusRegistry.in_progress_status];
984
+ }
985
+ else if (options.lifecycleBucket === "open") {
986
+ lifecycleStatus = [...statusRegistry.active_statuses]
987
+ .filter((entry) => entry !== statusRegistry.in_progress_status)
988
+ .sort((left, right) => left.localeCompare(right));
989
+ }
990
+ const resolvedStatus = explicitStatus ??
991
+ lifecycleStatus ??
992
+ resolveStatusFilter(status, statusRegistry);
982
993
  const explicitAllStatuses = isStatusAllFilterInput(options.status);
983
994
  const effectiveOptions = explicitStatus || explicitAllStatuses
984
995
  ? { ...options, excludeTerminal: false }
985
996
  : options;
986
- const filtersStatus = explicitAllStatuses
987
- ? "all"
988
- : resolvedStatus === undefined
989
- ? effectiveOptions.excludeTerminal === true
990
- ? null
991
- : "all"
992
- : resolvedStatus.length === 1
993
- ? resolvedStatus[0]
994
- : resolvedStatus;
997
+ let filtersStatus = "all";
998
+ if (explicitAllStatuses) {
999
+ filtersStatus = "all";
1000
+ }
1001
+ else if (explicitStatus !== undefined) {
1002
+ filtersStatus =
1003
+ explicitStatus.length === 1 ? explicitStatus[0] : explicitStatus;
1004
+ }
1005
+ else if (options.lifecycleBucket !== undefined) {
1006
+ filtersStatus = options.lifecycleBucket;
1007
+ }
1008
+ else if (resolvedStatus !== undefined) {
1009
+ filtersStatus =
1010
+ resolvedStatus.length === 1 ? resolvedStatus[0] : resolvedStatus;
1011
+ }
1012
+ else if (effectiveOptions.excludeTerminal === true) {
1013
+ filtersStatus = null;
1014
+ }
995
1015
  return {
996
1016
  resolvedStatus,
997
1017
  explicitAllStatuses,
@@ -1045,6 +1065,7 @@ async function tryLoadIndexedListPage(params) {
1045
1065
  "includeBody",
1046
1066
  "excludeTerminal",
1047
1067
  "dependencyBlocked",
1068
+ "lifecycleBucket",
1048
1069
  "noTruncate",
1049
1070
  "projectionCommand",
1050
1071
  "truncate",
@@ -1281,4 +1302,4 @@ export const _testOnly = {
1281
1302
  withTreeMetadata,
1282
1303
  };
1283
1304
  //# sourceMappingURL=list.js.map
1284
- //# debugId=93e8c187-e198-50fc-bf2c-7dae2ea42219
1305
+ //# debugId=ccdb7d16-4f38-58d4-a19d-4ab1516cb1d7
@@ -1,8 +1,8 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8a3a82a1-9e3d-555f-9111-3c3e19887f75")}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]="95e9def9-3f48-5108-8a17-0747fcf64f2d")}catch(e){}}();
3
3
  import { EXIT_CODE } from "../core/shared/constants.js";
4
4
  import { PmCliError } from "../core/shared/errors.js";
5
- import { transferMutationStdinTokenPolicy, } from "./runtime-primitives.js";
5
+ import { transferMutationStdinTokenPolicy } from "./runtime-primitives.js";
6
6
  import { createUnknownSubcommandError } from "./agent/subcommand-recovery.js";
7
7
  import { resolvePmRoot } from "../core/store/paths.js";
8
8
  import { runEval } from "./eval.js";
@@ -14,6 +14,7 @@ import { listMutationEvents } from "./mutation-events.js";
14
14
  import { parseRuntimeInteger, readRuntimeString, readRuntimeStringArray, } from "./runtime-input.js";
15
15
  import { runEvent, runMeet, runRemind, } from "./scheduling-shortcuts.js";
16
16
  import { createWorkspaceSnapshot, deleteWorkspaceSnapshot, inspectWorkspaceSnapshot, listWorkspaceSnapshots, planWorkspaceSnapshotRestore, restoreWorkspaceSnapshotWithRecovery, } from "./workspace-snapshot.js";
17
+ import { readWorkspacePosition } from "./governance/workspace-position.js";
17
18
  function mergedInput(context) {
18
19
  const input = { ...context.args, ...context.options };
19
20
  return transferMutationStdinTokenPolicy(context.options, input);
@@ -114,11 +115,14 @@ export function runRuntimeMergeAction(context) {
114
115
  export function runRuntimeWorkspaceAction(context) {
115
116
  const input = mergedInput(context);
116
117
  const subcommand = requiredString(input, "subcommand");
118
+ if (subcommand === "position") {
119
+ return readWorkspacePosition(context.global);
120
+ }
117
121
  if (subcommand !== "snapshot") {
118
122
  throw createUnknownSubcommandError({
119
123
  command_path: "workspace",
120
124
  token: subcommand,
121
- allowed: ["snapshot"],
125
+ allowed: ["position", "snapshot"],
122
126
  display_name: "workspace",
123
127
  });
124
128
  }
@@ -171,4 +175,4 @@ export function runRuntimeSchedulingAction(context) {
171
175
  return runRemind(title, input, context.global);
172
176
  }
173
177
  //# sourceMappingURL=runtime-extended-actions.js.map
174
- //# debugId=8a3a82a1-9e3d-555f-9111-3c3e19887f75
178
+ //# debugId=95e9def9-3f48-5108-8a17-0747fcf64f2d
@@ -4,7 +4,7 @@
4
4
  * Owns typed schema customization primitives shared by SDK, CLI, and MCP consumers.
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]="6112923d-5e06-5839-b452-a32818c6398d")}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]="264088a5-09d1-52ed-8b12-af00392e1a5f")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "./environment/tracker-preflight.js";
9
9
  import path from "node:path";
10
10
  import { mkdir } from "node:fs/promises";
@@ -422,6 +422,16 @@ export async function runSchemaAddStatus(id, options, global) {
422
422
  // --role/--alias preserves metadata defined in settings.schema.statuses, not
423
423
  // only what is already in statuses.json.
424
424
  const baseDefinition = toExistingStatusDefinition(statusRegistry.by_id.get(normalized.id));
425
+ const effectiveRoles = normalized.roles ?? baseDefinition?.roles ?? [];
426
+ if (effectiveRoles.length === 0) {
427
+ throw new PmCliError(`Status "${normalized.id}" requires at least one lifecycle role. Re-run with --role active, --role blocked, --role draft, or an appropriate terminal/default role.`, EXIT_CODE.USAGE, {
428
+ code: "status_lifecycle_role_required",
429
+ examples: [
430
+ `pm schema add-status "${escapeForDoubleQuotes(normalized.id)}" --role active`,
431
+ `pm schema add-status "${escapeForDoubleQuotes(normalized.id)}" --role blocked`,
432
+ ],
433
+ });
434
+ }
425
435
  const warnings = [];
426
436
  const author = resolveAuthor(options.author, settings.author_default);
427
437
  const governance = resolveGovernanceKnobs(settings);
@@ -1364,4 +1374,4 @@ export const _testOnlySchemaCommand = {
1364
1374
  workflowSlotsReferencing,
1365
1375
  };
1366
1376
  //# sourceMappingURL=schema.js.map
1367
- //# debugId=6112923d-5e06-5839-b452-a32818c6398d
1377
+ //# debugId=264088a5-09d1-52ed-8b12-af00392e1a5f
@@ -206,6 +206,21 @@ declare function resolveDirectRunnerSubcommand(parsed: {
206
206
  } | null): string | undefined;
207
207
  declare function firstDirectTestRunnerSubcommand(executable: string, args: string[]): string | undefined;
208
208
  declare function segmentInvokesRecursiveTestAll(segment: string): boolean;
209
+ /** Describes the SDK-owned safety policy applied when a linked command is recorded. */
210
+ export interface LinkedTestCommandSafetyClassification {
211
+ /** Whether intake accepts the command before provenance checks at execution time. */
212
+ accepted: true;
213
+ /** Capability-oriented command family, independent of shell wrapping. */
214
+ command_kind: "direct_runner" | "sandbox_runner" | "other";
215
+ /** Tracker isolation is injected by the linked-test runtime for every command. */
216
+ tracker_isolation: "runtime_injected";
217
+ /** Stored-command provenance and explicit acknowledgment form the execution trust boundary. */
218
+ trust_boundary: "provenance";
219
+ /** Human guidance for reproducible execution without presenting string shape as enforcement. */
220
+ advisory: string;
221
+ }
222
+ /** Classify linked-test commands without pretending string shape is a security boundary. */
223
+ export declare function classifyLinkedTestCommandSafety(command: string): LinkedTestCommandSafetyClassification;
209
224
  declare function parseLinkedTestTimeoutSeconds(timeoutSecondsRaw: string | undefined, timeoutAliasRaw: string | undefined): number | undefined;
210
225
  declare function parseAddJsonEntries(raw: string[] | undefined): LinkedTest[];
211
226
  declare function endLinkedTestProgress(context: LinkedTestProgressContext, executionResult: Pick<LinkedTestExecutionResult, "timedOut" | "maxBufferExceeded" | "outputTruncated" | "exitCode" | "signal">, startedAt: number, mode: LinkedTestProgressMode): void;
@@ -4,7 +4,7 @@
4
4
  * Implements the pm test 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]="de5bc6bf-fe31-5643-a809-ee9ca52aac48")}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]="03f2f710-3b96-5671-85fa-d8ea4726ee86")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
9
  import { spawn } from "node:child_process";
10
10
  import { cp, mkdir, mkdtemp, open, readdir, rm, symlink, } from "node:fs/promises";
@@ -388,14 +388,7 @@ function commandUsesSandboxRunner(normalizedCommand) {
388
388
  normalizedCommand.includes("node ./scripts/run-tests.mjs ") ||
389
389
  normalizedCommand.endsWith("node ./scripts/run-tests.mjs"));
390
390
  }
391
- function segmentHasExplicitSandboxEnv(normalizedSegment) {
392
- const hasExplicitPmPath = /\bpm_path\s*=/.test(normalizedSegment) ||
393
- /\$env:pm_path\s*=/.test(normalizedSegment);
394
- const hasExplicitPmGlobalPath = /\bpm_global_path\s*=/.test(normalizedSegment) ||
395
- /\$env:pm_global_path\s*=/.test(normalizedSegment);
396
- return hasExplicitPmPath && hasExplicitPmGlobalPath;
397
- }
398
- function segmentInvokesUnsafeDirectTestRunner(normalizedSegment) {
391
+ function segmentInvokesDirectTestRunner(normalizedSegment) {
399
392
  const rawTokens = normalizedSegment
400
393
  .split(" ")
401
394
  .filter((token) => token.length > 0);
@@ -404,45 +397,62 @@ function segmentInvokesUnsafeDirectTestRunner(normalizedSegment) {
404
397
  return false;
405
398
  }
406
399
  const [executable, ...args] = tokens;
400
+ const shellCommandFlagPattern = SHELL_COMMAND_FLAG_PATTERNS.get(executable);
401
+ if (shellCommandFlagPattern) {
402
+ const commandFlagIndex = args.findIndex((argument) => shellCommandFlagPattern.test(argument));
403
+ return (commandFlagIndex >= 0 &&
404
+ segmentInvokesDirectTestRunner(args.slice(commandFlagIndex + 1).join(" ")));
405
+ }
407
406
  if (executable === "vitest" ||
408
407
  executable.endsWith("/vitest") ||
409
408
  executable.endsWith("/vitest.mjs")) {
410
409
  return true;
411
410
  }
412
411
  if (executable === "node") {
413
- return nodeArgsInvokeUnsafeDirectTestRunner(args);
412
+ return nodeArgsInvokeDirectTestRunner(args);
414
413
  }
415
- return packageManagerInvokesUnsafeDirectTestRunner(executable, args);
414
+ return packageManagerInvokesDirectTestRunner(executable, args);
416
415
  }
417
- function nodeArgsInvokeUnsafeDirectTestRunner(args) {
416
+ function nodeArgsInvokeDirectTestRunner(args) {
418
417
  return (args.includes("--test") ||
419
418
  args.some((arg) => arg === "vitest" ||
420
419
  arg === "vitest.mjs" ||
421
420
  arg.endsWith("/vitest") ||
422
421
  arg.endsWith("/vitest.mjs")));
423
422
  }
424
- function packageManagerInvokesUnsafeDirectTestRunner(executable, args) {
423
+ function packageManagerInvokesDirectTestRunner(executable, args) {
425
424
  if (executable === "npx" || executable === "bunx") {
426
425
  return isDirectTestRunnerSubcommand(parseNpxCommand(args)?.command);
427
426
  }
428
427
  if (executable === "pnpm" || executable === "npm") {
429
428
  return (isDirectTestRunnerSubcommand((executable === "pnpm"
430
429
  ? parsePnpmDlxCommand(args)
431
- : parseNpmExecCommand(args))?.command) || firstDirectTestRunnerSubcommand(executable, args) === "vitest");
430
+ : parseNpmExecCommand(args))?.command) ||
431
+ isDirectTestRunnerSubcommand(firstDirectTestRunnerSubcommand(executable, args)));
432
432
  }
433
433
  return ((executable === "yarn" || executable === "bun") &&
434
- firstDirectTestRunnerSubcommand(executable, args) === "vitest");
434
+ isDirectTestRunnerSubcommand(firstDirectTestRunnerSubcommand(executable, args)));
435
435
  }
436
- function assertSandboxSafeTestRunnerCommand(command) {
436
+ /** Classify linked-test commands without pretending string shape is a security boundary. */
437
+ export function classifyLinkedTestCommandSafety(command) {
437
438
  const normalized = normalizeCommandForValidation(command);
438
439
  const segments = splitNormalizedCommandSegments(normalized);
439
- const hasUnsafeDirectRunnerSegment = segments.some((segment) => !commandUsesSandboxRunner(segment) &&
440
- segmentInvokesUnsafeDirectTestRunner(segment) &&
441
- !segmentHasExplicitSandboxEnv(segment));
442
- if (!hasUnsafeDirectRunnerSegment) {
443
- return;
444
- }
445
- throw new PmCliError('Linked test runner commands must be sandbox-safe: use "node scripts/run-tests.mjs <test|coverage>", use a package-manager script such as "pnpm test", or include PM_PATH=... PM_GLOBAL_PATH=... INLINE in the command string (exporting them in your shell environment is not checked). Example: "PM_PATH=/tmp/pm-x PM_GLOBAL_PATH=/tmp/pm-x-g vitest run".', EXIT_CODE.USAGE);
440
+ const directRunner = segments.some((segment) => !commandUsesSandboxRunner(segment) &&
441
+ segmentInvokesDirectTestRunner(segment));
442
+ const sandboxRunner = segments.some(commandUsesSandboxRunner);
443
+ return {
444
+ accepted: true,
445
+ command_kind: directRunner
446
+ ? "direct_runner"
447
+ : sandboxRunner
448
+ ? "sandbox_runner"
449
+ : "other",
450
+ tracker_isolation: "runtime_injected",
451
+ trust_boundary: "provenance",
452
+ advisory: directRunner
453
+ ? "Accepted with runtime-injected tracker isolation. Prefer the repository sandbox runner when available for reproducible build and coverage setup."
454
+ : "Accepted with runtime-injected tracker isolation and provenance checks before execution.",
455
+ };
446
456
  }
447
457
  function getRuntimeSafetySkipReason(command) {
448
458
  if (!invokesRecursiveTestAllCommand(command))
@@ -464,7 +474,6 @@ function parseAddEntry(entry) {
464
474
  throw new PmCliError("--add requires command=<value> or a bare command (path=<value> is optional metadata)", EXIT_CODE.USAGE);
465
475
  }
466
476
  assertNoRecursiveTestAllCommand(command);
467
- assertSandboxSafeTestRunnerCommand(command);
468
477
  return {
469
478
  command,
470
479
  path: trimLinkedTestEntryField(kv.path),
@@ -516,7 +525,6 @@ function parseAddJsonEntries(raw) {
516
525
  throw new PmCliError("--add-json requires a non-empty command string", EXIT_CODE.USAGE);
517
526
  }
518
527
  assertNoRecursiveTestAllCommand(command);
519
- assertSandboxSafeTestRunnerCommand(command);
520
528
  }
521
529
  return parsed;
522
530
  });
@@ -1325,7 +1333,7 @@ function commandUsesTestNameFilter(command) {
1325
1333
  return true;
1326
1334
  }
1327
1335
  return splitNormalizedCommandSegments(normalized).some((segment) => /(?:^|\s)-t(?:=|\s)/u.test(segment) &&
1328
- segmentInvokesUnsafeDirectTestRunner(segment));
1336
+ segmentInvokesDirectTestRunner(segment));
1329
1337
  }
1330
1338
  function createLinkedTestSandboxLayout(sandboxRoot) {
1331
1339
  return {
@@ -2201,4 +2209,4 @@ export const _testOnlyTestCommand = {
2201
2209
  summarizeRunResultStatuses,
2202
2210
  };
2203
2211
  //# sourceMappingURL=execution.js.map
2204
- //# debugId=de5bc6bf-fe31-5643-a809-ee9ca52aac48
2212
+ //# debugId=03f2f710-3b96-5671-85fa-d8ea4726ee86
@@ -12,7 +12,7 @@ pm search "<request keywords>" --limit 10
12
12
  pm list --status open --limit 20
13
13
  pm list --status in_progress --limit 20
14
14
  pm init --agent-guidance status
15
- pm install guide-shell --project
15
+ pm package install guide-shell --project
16
16
  pm guide workflows
17
17
  ```
18
18
 
@@ -84,7 +84,7 @@ Modern MCP clients may supply a bounded
84
84
  `io.modelcontextprotocol/clientInfo.provenance` map in each request's `_meta`.
85
85
  The server retains only valid dimension names and trimmed values, then resolves
86
86
  that map inside the invocation-scoped identity context for that request. The
87
- bounded `2025-06-18` adapter accepts the same map during legacy `initialize`.
87
+ bounded initialize-era adapter accepts the same map during legacy `initialize`.
88
88
  A missing MCP signal is recorded as explicit `null`; it is never confused with
89
89
  a legacy entry that predates the dimension.
90
90
 
@@ -158,8 +158,8 @@ summary. No history entry is rewritten.
158
158
 
159
159
  MCP 2026-07-28 reads `io.modelcontextprotocol/clientInfo` independently from
160
160
  every request's `_meta` and scopes only that request to the client signal. The
161
- bounded legacy adapter still reads `clientInfo` during `2025-06-18`
162
- `initialize`. Optional host-provided `model`, `session`, `provenance`, and
161
+ bounded legacy adapter still reads `clientInfo` during an initialize-era
162
+ handshake. Optional host-provided `model`, `session`, `provenance`, and
163
163
  `episode` fields are supported, but version is not misclassified as a model or
164
164
  session. Provenance keys must use the bounded
165
165
  lowercase dimension vocabulary; blank, malformed, and oversized data is
@@ -134,8 +134,8 @@ pnpm smoke:codex-plugin
134
134
  ```bash
135
135
  pm contracts --schema-only --json
136
136
  pm contracts --command extension --flags-only --json
137
- pm extension --doctor --project --detail summary --strict-exit
138
- pm extension --reload --project
137
+ pm package doctor --project --detail summary --strict-exit
138
+ pm package reload --project
139
139
  ```
140
140
 
141
141
  Why this matters:
@@ -188,7 +188,7 @@ The authoritative plugin version is `plugins/pm-claude/.claude-plugin/plugin.jso
188
188
 
189
189
  The MCP server uses JSON-RPC 2.0 over stdio with canonical protocol version
190
190
  `2026-07-28`. A bounded legacy path remains for unversioned older hosts, with
191
- `2025-06-18` initialize available to enrich client identity; current hosts
191
+ initialize-era handshakes available to enrich client identity; current hosts
192
192
  discover the server and send metadata on every request.
193
193
 
194
194
  ## Extension Policy Diagnostics
package/docs/COMMANDS.md CHANGED
@@ -67,7 +67,7 @@ JSON ceiling; TOON uses the smaller default agent ceiling.
67
67
  | Packages | `install`, `upgrade`, `package`, `packages`, `extension`, package/extension command groups | install, upgrade, manage, and run package-backed extension commands |
68
68
  | Machines | `contracts`, `help`, optional `guide`/`completion` | command contracts plus optional guide-shell docs routing and shell helpers |
69
69
 
70
- `†` `test-runs` subcommands are provided by the optional `linked-test-adapters` package (`pm install linked-test-adapters --project`).
70
+ `†` `test-runs` subcommands are provided by the optional `linked-test-adapters` package (`pm package install linked-test-adapters --project`).
71
71
 
72
72
  ## Bootstrap
73
73
 
@@ -113,21 +113,21 @@ Use `--with-packages` for one-step agent setup when bundled package commands sho
113
113
 
114
114
  ```bash
115
115
  pm package # bare command defaults to --explore (list installed)
116
- pm install '*' --project
116
+ pm package install '*' --project
117
117
  pm package catalog --project
118
118
  pm package manage --project --output-format json
119
- pm install npm:@scope/pm-package --project
119
+ pm package install npm:@scope/pm-package --project
120
120
  pm package describe --project # by-name surface map of every loaded package
121
121
  pm package describe my-package --markdown --output docs/my-package-reference.md
122
122
  pm package doctor --project --detail summary
123
123
  pm package migrate --project --dry-run --json
124
124
  pm package migrate --project --json
125
- pm upgrade --dry-run
126
- pm upgrade --packages-only
127
- pm upgrade --cli-only --repair
125
+ pm package upgrade --dry-run
126
+ pm package upgrade --packages-only
127
+ pm package upgrade --cli-only --repair
128
128
  ```
129
129
 
130
- `pm install` and `pm package` are the preferred package-first workflow. `pm package` and `pm extension` bare invocations default to `--explore` so agents can list installed packages without remembering an action flag. `pm install '*'`, shell-expanded `pm install *`, and `pm install all` install bundled first-party packages. `pm extension` remains as a compatibility command for direct extension lifecycle operations.
130
+ `pm package` is the canonical package-first workflow. `pm package` and the hidden `pm extension` alias default to `--explore` on a bare invocation so agents can list installed packages without remembering an action flag. `pm package install '*'`, shell-expanded `pm package install *`, and `pm package install all` install bundled first-party packages. `pm install`, `pm upgrade`, and `pm extension` remain executable as deprecated compatibility spellings declared in `PM_COMMAND_ALIAS_CONTRACTS`; they emit a migration hint and must not appear in documentation or skills as instructions.
131
131
  `pm package catalog` emits one row per package, with every resolvable bundled
132
132
  alias preserved in `aliases`; totals therefore measure packages rather than
133
133
  alias-index entries. `pm package manage` participates in the universal read
@@ -141,7 +141,7 @@ the choice ambiguous and provides explicit bare and `npm:` retry commands.
141
141
  durable workspace-history receipts; a successful migration is skipped on later
142
142
  processes, while a failed migration remains retryable. `extension migrate` is
143
143
  the compatibility spelling.
144
- When package-owned commands are unavailable, usage guidance includes an install-ready retry (for example `pm install calendar`, `pm install search-advanced`, `pm install governance-audit`, or `pm install guide-shell`).
144
+ When package-owned commands are unavailable, usage guidance includes an install-ready retry (for example `pm package install calendar`, `pm package install search-advanced`, `pm package install governance-audit`, or `pm package install guide-shell`).
145
145
 
146
146
  ## Triage
147
147
 
@@ -669,7 +669,7 @@ Tracker references: [pm-72xf](../.agents/pm/features/pm-72xf.toon).
669
669
 
670
670
  ## Templates
671
671
 
672
- After `pm install templates --project`, `pm templates` lists both saved templates and built-in starters:
672
+ After `pm package install templates --project`, `pm templates` lists both saved templates and built-in starters:
673
673
 
674
674
  ```bash
675
675
  pm templates
@@ -804,7 +804,7 @@ pm test <id> --run --only-last
804
804
  pm test-all --status in_progress --progress
805
805
  ```
806
806
 
807
- Linked test commands should be sandbox-safe. Prefer `node scripts/run-tests.mjs ...` for repo-local test suites; normal package-manager scripts such as `pnpm test` and `npm run test` are accepted because linked-test execution injects temporary `PM_PATH` and `PM_GLOBAL_PATH`. Direct runner binaries such as `vitest` or `node --test` still need the wrapper or explicit inline sandbox env. The two-token form `--add command "npm test -- parser"` (and `--add path "..."` / `--remove command "..."`) is accepted when the value is quoted into a single shell argument; it is normalized to `--add command=...` before parsing. Use `--add-json` when command strings contain commas, nested quotes, shell variables, or `--` separators that are awkward to preserve through CSV-style `--add` parsing. Linked tests retain append order; consequently `--only-last` always selects the most recently added stored test. `--match`, `--only-index`, and `--only-last` select which linked tests execute without mutating the stored linked-test list.
807
+ Linked-test execution injects temporary `PM_PATH` and `PM_GLOBAL_PATH` for every command and checks stored-command provenance before process creation. Direct runner binaries such as `vitest` or `node --test`, shell-wrapped equivalents, package-manager scripts, and non-Node runners are accepted consistently; prefer `node scripts/run-tests.mjs ...` when available because it also reproduces repository build, coverage, and cleanup policy. The two-token form `--add command "npm test -- parser"` (and `--add path "..."` / `--remove command "..."`) is accepted when the value is quoted into a single shell argument; it is normalized to `--add command=...` before parsing. Use `--add-json` when command strings contain commas, nested quotes, shell variables, or `--` separators that are awkward to preserve through CSV-style `--add` parsing. Linked tests retain append order; consequently `--only-last` always selects the most recently added stored test. `--match`, `--only-index`, and `--only-last` select which linked tests execute without mutating the stored linked-test list.
808
808
 
809
809
  Strict linked-test guards:
810
810
 
@@ -818,7 +818,7 @@ pm test <id> --run \
818
818
 
819
819
  ## Search Reindex and Eval
820
820
 
821
- `reindex` is provided by the `search-advanced` package (`pm install search-advanced --project`).
821
+ `reindex` is provided by the `search-advanced` package (`pm package install search-advanced --project`).
822
822
 
823
823
  ```bash
824
824
  pm reindex --mode keyword
@@ -1240,7 +1240,7 @@ only after selecting the exact path.
1240
1240
 
1241
1241
  ## Completion
1242
1242
 
1243
- `pm completion` is provided by the optional `guide-shell` package (`pm install guide-shell --project`).
1243
+ `pm completion` is provided by the optional `guide-shell` package (`pm package install guide-shell --project`).
1244
1244
 
1245
1245
  ```bash
1246
1246
  pm completion bash
@@ -210,7 +210,7 @@ Markdown item files are treated as legacy migration input only. Mutations always
210
210
  Most commands default to sparse TOON:
211
211
 
212
212
  ```bash
213
- pm list-open --limit 10
213
+ pm list --status open --limit 10
214
214
  ```
215
215
 
216
216
  Use JSON for strict machine parsing:
@@ -79,6 +79,8 @@ The repository example is [config/defect-recurrence-policy.json](../config/defec
79
79
 
80
80
  Repository policy validation rejects duplicate ids, absent historical examples, missing family negative controls, invalid taxonomy values, and budgets outside zero through one. Deterministic sorting makes the serialized policy merge-friendly.
81
81
 
82
+ Register a family whenever a defect is recorded as a recurrence of an earlier one, meaning the new item carries a `recurs_from` edge to its predecessor. A recurrence with no family produces no local and no hosted protection, so the next instance is rediscovered by hand. Coverage of recorded recurrence lineages is not yet computed by any gate; that gap is tracked on [pm-7c27ep](../.agents/pm/issues/pm-7c27ep.toon).
83
+
82
84
  ## Defect Evidence on PM Items
83
85
 
84
86
  Projects can register the structured fields without changing the SDK:
@@ -41,13 +41,33 @@ request.
41
41
 
42
42
  ## Legacy boundary
43
43
 
44
- The sole supported legacy revision is `2025-06-18`, accepted through the
45
- existing stdio adapter. Unversioned requests stay on this legacy path because
46
- they cannot claim the current revision; `initialize` enriches their client
47
- identity but is not required for compatibility with older pm hosts. The
48
- adapter has no session id, does not affect modern requests, and is excluded
49
- from `server/discover`'s `supportedVersions` because it cannot be selected
50
- through modern per-request metadata.
44
+ Legacy means every revision that establishes a session with an `initialize`
45
+ handshake, which the canonical revision defines as `2025-11-25` and earlier.
46
+ The stdio adapter therefore accepts the full initialize-era set, newest first:
47
+
48
+ | Revision | Accepted at `initialize` | Notes |
49
+ |----------|--------------------------|-------|
50
+ | `2025-11-25` | yes | Final legacy revision; offered when a client omits `protocolVersion` |
51
+ | `2025-06-18` | yes | Earlier legacy revision retained for existing consumers |
52
+
53
+ `initialize` answers with the revision the client requested, because a legacy
54
+ client has no fall-forward mechanism and treats the answered version as the
55
+ negotiated one. A revision outside the set is refused with `-32022` and the
56
+ refusal names every supported revision, since that error text is the only
57
+ diagnostic such a client can surface.
58
+
59
+ `PM_MCP_LEGACY_PROTOCOL_VERSIONS` on the public SDK surface is the single
60
+ declaration of this set. The plugin MCP smoke gate reads it from the built SDK
61
+ and drives one real `initialize` per declared revision against the released
62
+ launcher, plus a negative control for an undeclared revision, so the accepted
63
+ set and the documented set cannot drift apart.
64
+
65
+ Unversioned requests stay on this legacy path because they cannot claim the
66
+ current revision; `initialize` enriches their client identity but is not
67
+ required for compatibility with older pm hosts. The adapter has no session id,
68
+ does not affect modern requests, and is excluded from `server/discover`'s
69
+ `supportedVersions` because it cannot be selected through modern per-request
70
+ metadata.
51
71
 
52
72
  The adapter is scheduled for removal only after published-client telemetry and
53
73
  release probes show no required legacy consumers for two consecutive release
@@ -58,7 +78,7 @@ windows. Removal is a reviewed compatibility change, never a history rewrite.
58
78
  - Stdio modern clients call `server/discover` with current request metadata,
59
79
  then send the same version and capability keys on every request.
60
80
  - Stdio legacy clients retain their existing response shapes and may use
61
- `initialize` with `2025-06-18` to supply client identity.
81
+ `initialize` with any accepted legacy revision to supply client identity.
62
82
  - Streamable HTTP requires `MCP-Protocol-Version` and `Mcp-Method` on every
63
83
  request. `Mcp-Name` is required only for `prompts/get`, `resources/read`, and
64
84
  `tools/call`; other methods omit it. Schema-declared `x-mcp-header` values are
@@ -13,6 +13,7 @@ evidence or an explicit open obligation.
13
13
  | Header mismatch `-32020` and missing capability `-32021` | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented in SDK, stdio, and Streamable HTTP | SDK negative controls and `tests/integration/mcp-streamable-http.spec.ts` |
14
14
  | Required result `resultType`; legacy omission means complete only at compatibility boundary | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented for modern pm results | SDK unit and modern direct-server tests |
15
15
  | No modern initialize, initialized notification, ping, or protocol session | [pm-sqvshj](../.agents/pm/decisions/pm-sqvshj.toon) | Implemented with bounded legacy stdio adapter | modern removed-method and legacy handshake tests |
16
+ | Legacy interoperability covers every initialize-era revision the spec names | [pm-edywqn](../.agents/pm/issues/pm-edywqn.toon) | Implemented: `2025-11-25` and `2025-06-18` accepted, requested revision echoed | `tests/integration/mcp-handshake.spec.ts` handshake matrix plus the plugin smoke `assertProtocolHandshakeMatrix` real-process gate and its negative control |
16
17
  | MRTR `input_required`, retry state, and reverse-request removal | [pm-rz9gep](../.agents/pm/features/pm-rz9gep.toon) | Implemented for SDK and stateless stdio adapter | `tests/unit/sdk/mcp/interactions.spec.ts`; direct server negative controls |
17
18
  | `subscriptions/listen`, request-scoped streams, no SSE resumability | [pm-v7e337](../.agents/pm/features/pm-v7e337.toon) | Implemented locally; packed and published proof follows merge | subscription SDK, stdio, HTTP, backpressure, disconnect, and retry tests |
18
19
  | 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` |
@@ -7,7 +7,7 @@ Tracker references: [pm-v7e337](../.agents/pm/features/pm-v7e337.toon),
7
7
  pm exposes the same MCP 2026-07-28 dispatcher through two adapters:
8
8
 
9
9
  - `pm-mcp` is the local JSON-RPC/stdio process. It retains a bounded
10
- `2025-06-18` compatibility adapter for existing local consumers.
10
+ initialize-era compatibility adapter for existing local consumers.
11
11
  - `pm-mcp-http` is the canonical sessionless Streamable HTTP POST process. It
12
12
  accepts only modern request-local protocol metadata and never creates an
13
13
  MCP session.
@@ -155,7 +155,9 @@ an unlisted source path cannot create that exemption. Any canonical match for a
155
155
  removed method, session header, SSE resume mechanism, legacy
156
156
  resource-subscription method, or deprecated server policy fails the gate.
157
157
 
158
- The compatibility adapter supports only protocol `2025-06-18` on local stdio.
158
+ The compatibility adapter supports the initialize-era revisions declared by
159
+ `PM_MCP_LEGACY_PROTOCOL_VERSIONS` (`2025-11-25` and `2025-06-18`) on local
160
+ stdio.
159
161
  It may be removed after telemetry and installed-consumer probes show no
160
162
  required legacy clients for two consecutive release windows. Deprecated
161
163
  2026-07-28 fields remain available only where the normative registry requires
@@ -43,7 +43,7 @@ pm context --limit 10
43
43
  pm search "<request keywords>" --limit 10
44
44
  pm list --status open --limit 20
45
45
  pm list --status in_progress --limit 20
46
- pm install guide-shell --project
46
+ pm package install guide-shell --project
47
47
  pm guide workflows
48
48
  ```
49
49
 
package/docs/README.md CHANGED
@@ -7,7 +7,7 @@ This directory is the public documentation home for `pm-cli`. It is organized fo
7
7
  `pm guide` is provided by the optional `guide-shell` package. Install it when local in-CLI documentation routing is useful:
8
8
 
9
9
  ```bash
10
- pm install guide-shell --project
10
+ pm package install guide-shell --project
11
11
  pm guide
12
12
  pm guide quickstart
13
13
  pm guide commands --depth standard
@@ -72,6 +72,7 @@ pm guide release --json
72
72
  - [SDK Evidence Traceability and Integrity](SDK_EVIDENCE_TRACEABILITY.md) - reverse source-to-item lookup, atomic evidence replacement, no-op history, linked-test collision classification, and telemetry drain receipts.
73
73
  - [SDK Context and Evidence Contracts](SDK_CONTEXT_EVIDENCE_CONTRACTS.md) - material omission receipts, scoped preflight activation, truthful merge preference, claim-race classification, and versioned history hashes.
74
74
  - [Reproducible Workspaces and Snapshots](REPRODUCIBLE_WORKSPACES.md) - deterministic SDK recipes and content-addressed authoritative tracker restore points.
75
+ - [Workspace Position and Lifecycle Roles](WORKSPACE_POSITION_AND_LIFECYCLE.md) - role-safe custom workflows plus one bounded merge-fence, receipt, history-drift, and next-action SDK read.
75
76
  - [Portable Corpus Shapes](CORPUS_SHAPES.md) - versioned SDK populations for realistic benchmarks, evaluations, and package tests.
76
77
  - [Agent UX Contracts](AGENT_UX_CONTRACTS.md) - ordering-cycle advisories, graph count units, collision safety, compact context, ownership wording, and recovery behavior.
77
78
  - [Packages and Extensions](EXTENSIONS.md) - package install workflows, runtime extension lifecycle, and API reference.
@@ -144,7 +144,7 @@ consumer therefore cannot interpret the missing command or action arrays as a
144
144
  successful empty contract.
145
145
 
146
146
  ```bash
147
- pm list-open --output-include id,title,status --output-limit 10
147
+ pm list --status open --output-include id,title,status --output-limit 10
148
148
  pm context --for orient --output-budget 900 --output-format toon
149
149
  pm search "runtime contracts" --output-limit 5 --output-format json
150
150
  pm stats --output-row-contract
@@ -129,7 +129,7 @@ pm reindex --mode hybrid
129
129
  If the command is absent, recovery is a two-step executable sequence:
130
130
 
131
131
  ```bash
132
- pm install search-advanced --project
132
+ pm package install search-advanced --project
133
133
  pm reindex --mode hybrid
134
134
  ```
135
135