@unbrained/pm-cli 2026.9.20 → 2026.9.21

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 (34) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +11 -0
  3. package/dist/cli-bundle/bundle-manifest.json +28 -28
  4. package/dist/cli-bundle/chunks/{chunk-33R5PEKI.js → chunk-4SI67A2F.js} +2 -2
  5. package/dist/cli-bundle/chunks/{chunk-TTFVQB4S.js → chunk-NHRB3L5T.js} +2 -2
  6. package/dist/cli-bundle/chunks/{chunk-2FEKKSLN.js → chunk-SDLBF4PY.js} +43 -43
  7. package/dist/cli-bundle/chunks/{register-mutation-EVRYSU72.js → register-mutation-DXES37MA.js} +2 -2
  8. package/dist/cli-bundle/main.js +2 -2
  9. package/dist/cli-bundle/sdk-core.js +21 -21
  10. package/dist/cli-bundle/sdk-runtime.js +1 -1
  11. package/dist/cli-bundle/sdk-testing.js +1 -1
  12. package/dist/cli-bundle/sdk.js +1 -1
  13. package/dist/sdk/completion/bash.d.ts +1 -1
  14. package/dist/sdk/completion/bash.js +1 -1
  15. package/docs/README.md +1 -0
  16. package/docs/VALIDATION_PORTABILITY.md +82 -0
  17. package/marketplace.json +2 -2
  18. package/package.json +5 -5
  19. package/packages/pm-beads/package.json +1 -1
  20. package/packages/pm-calendar/package.json +1 -1
  21. package/packages/pm-command-kit/package.json +1 -1
  22. package/packages/pm-digital-twin/package.json +1 -1
  23. package/packages/pm-governance-audit/package.json +1 -1
  24. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +23 -17
  25. package/packages/pm-guide-shell/package.json +1 -1
  26. package/packages/pm-kanban/package.json +1 -1
  27. package/packages/pm-lifecycle-hooks/package.json +1 -1
  28. package/packages/pm-linked-test-adapters/package.json +1 -1
  29. package/packages/pm-search-advanced/package.json +1 -1
  30. package/packages/pm-templates/package.json +1 -1
  31. package/packages/pm-todos/package.json +1 -1
  32. package/packages/pm-vcs/package.json +1 -1
  33. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  34. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Runtime contracts and behavior for packages/pm guide shell/extensions/guide shell/runtime.
2
+ * Adapt package commands to public SDK guide/completion operations and preserve their Markdown, script and word-list transports.
3
3
  *
4
4
  * @module packages/pm-guide-shell/extensions/guide-shell/runtime
5
5
  */
@@ -27,6 +27,7 @@ import {
27
27
  type ServiceOverrideContext,
28
28
  } from "@unbrained/pm-cli/sdk";
29
29
 
30
+ /** Resolve the explicit topic before positional input and retain only SDK-supported guide options. */
30
31
  function normalizeGuideOptions(
31
32
  args: string[],
32
33
  options: Record<string, unknown>,
@@ -44,6 +45,7 @@ function normalizeGuideOptions(
44
45
  };
45
46
  }
46
47
 
48
+ /** Choose the shell with a Bash default and normalize camel-case or snake-case choice options. */
47
49
  function normalizeCompletionOptions(
48
50
  args: string[],
49
51
  options: Record<string, unknown>,
@@ -66,6 +68,7 @@ function normalizeCompletionOptions(
66
68
  };
67
69
  }
68
70
 
71
+ /** Return distinct nonblank runtime type names in stable locale order without inventing fallback types. */
69
72
  function collectTypeNames(
70
73
  typeRegistry: ReturnType<typeof resolveItemTypeRegistry>,
71
74
  ): string[] {
@@ -79,12 +82,7 @@ function collectTypeNames(
79
82
  ].sort((left, right) => left.localeCompare(right));
80
83
  }
81
84
 
82
- function collectTypeToFolder(
83
- typeRegistry: ReturnType<typeof resolveItemTypeRegistry>,
84
- ): Record<string, string> {
85
- return typeRegistry.type_to_folder;
86
- }
87
-
85
+ /** Extract nonblank workflow status identifiers in stable locale order for helper responses. */
88
86
  function collectStatusNames(
89
87
  statusRegistry: ReturnType<typeof resolveRuntimeStatusRegistry>,
90
88
  ): string[] {
@@ -156,6 +154,7 @@ async function buildCompletionRuntimeConfig(global: GlobalOptions): Promise<Comp
156
154
  };
157
155
  }
158
156
 
157
+ /** Accept only non-array objects as output envelopes; primitive and array results remain unwrapped. */
159
158
  function payloadRecord(payload: unknown): Record<string, unknown> | undefined {
160
159
  return typeof payload === "object" &&
161
160
  payload !== null &&
@@ -164,15 +163,18 @@ function payloadRecord(payload: unknown): Record<string, unknown> | undefined {
164
163
  : undefined;
165
164
  }
166
165
 
166
+ /** Honor an explicit JSON envelope format and otherwise select the default human-readable transport. */
167
167
  function readPayloadFormat(payload: unknown): "toon" | "json" {
168
168
  return payloadRecord(payload)?.format === "json" ? "json" : "toon";
169
169
  }
170
170
 
171
+ /** Unwrap an own result property while preserving bare results and explicit undefined payload values. */
171
172
  function readPayloadResult(payload: unknown): unknown {
172
173
  const record = payloadRecord(payload);
173
174
  return record && Object.hasOwn(record, "result") ? record.result : payload;
174
175
  }
175
176
 
177
+ /** Trim and deduplicate nonblank string tags across all items, then sort the helper word list. */
176
178
  function collectTagsFromItems(items: ItemMetadata[]): string[] {
177
179
  const tagSet = new Set<string>();
178
180
  for (const item of items) {
@@ -186,6 +188,7 @@ function collectTagsFromItems(items: ItemMetadata[]): string[] {
186
188
  return [...tagSet].sort((left, right) => left.localeCompare(right));
187
189
  }
188
190
 
191
+ /** Read only string entries from the requested helper collection, returning no choices for malformed results. */
189
192
  function readStringArrayResult(
190
193
  result: unknown,
191
194
  key: "tags" | "statuses" | "types",
@@ -199,6 +202,7 @@ function readStringArrayResult(
199
202
  : [];
200
203
  }
201
204
 
205
+ /** Serialize explicit JSON or the whitespace-delimited helper protocol, always terminating output with a newline. */
202
206
  function renderJsonOrWords(
203
207
  payload: unknown,
204
208
  result: unknown,
@@ -210,6 +214,7 @@ function renderJsonOrWords(
210
214
  return `${readStringArrayResult(result, key).join(" ")}\n`;
211
215
  }
212
216
 
217
+ /** Render explicit JSON or a generated script with a trailing newline; defer unsupported result shapes. */
213
218
  function renderCompletionPackageOutput(
214
219
  payload: unknown,
215
220
  result: unknown,
@@ -228,6 +233,7 @@ function renderCompletionPackageOutput(
228
233
  return null;
229
234
  }
230
235
 
236
+ /** Render guide Markdown or JSON according to SDK format precedence and defer generic TOON rendering. */
231
237
  function renderGuidePackageOutput(
232
238
  context: ServiceOverrideContext,
233
239
  result: unknown,
@@ -247,7 +253,7 @@ function renderGuidePackageOutput(
247
253
  return null;
248
254
  }
249
255
 
250
- /** Executes the guide package operation through the package runtime. */
256
+ /** Normalize package arguments and delegate guide discovery to the public SDK using the caller workspace options. */
251
257
  export async function runGuidePackage(
252
258
  args: string[],
253
259
  options: Record<string, unknown>,
@@ -256,7 +262,7 @@ export async function runGuidePackage(
256
262
  return runGuide(normalizeGuideOptions(args, options), global);
257
263
  }
258
264
 
259
- /** Executes the completion package operation through the package runtime. */
265
+ /** Render the requested shell using explicit choices plus the active workspace schema and package command paths. */
260
266
  export async function runCompletionPackage(
261
267
  args: string[],
262
268
  options: Record<string, unknown>,
@@ -273,7 +279,7 @@ export async function runCompletionPackage(
273
279
  );
274
280
  }
275
281
 
276
- /** Executes the completion tags package operation through the package runtime. */
282
+ /** Collect tags across configured item folders and formats; return an empty counted collection before initialization. */
277
283
  export async function runCompletionTagsPackage(
278
284
  global: GlobalOptions,
279
285
  ): Promise<{ tags: string[]; count: number }> {
@@ -284,7 +290,7 @@ export async function runCompletionTagsPackage(
284
290
  const settings = await readSettings(pmRoot);
285
291
  const registrations = getActiveExtensionRegistrations();
286
292
  const typeRegistry = resolveItemTypeRegistry(settings, registrations);
287
- const typeToFolder = collectTypeToFolder(typeRegistry);
293
+ const typeToFolder = typeRegistry.type_to_folder;
288
294
  const itemFormat = (
289
295
  settings.item_format === "json_markdown" ? "json_markdown" : "toon"
290
296
  ) as "toon" | "json_markdown";
@@ -302,7 +308,7 @@ export async function runCompletionTagsPackage(
302
308
  };
303
309
  }
304
310
 
305
- /** Executes the completion statuses package operation through the package runtime. */
311
+ /** Expose configured workflow status IDs with an exact count, or an empty collection before initialization. */
306
312
  export async function runCompletionStatusesPackage(
307
313
  global: GlobalOptions,
308
314
  ): Promise<{ statuses: string[]; count: number }> {
@@ -320,7 +326,7 @@ export async function runCompletionStatusesPackage(
320
326
  };
321
327
  }
322
328
 
323
- /** Executes the completion types package operation through the package runtime. */
329
+ /** Expose distinct configured and extension-provided type names with an exact count; tolerate an uninitialized workspace. */
324
330
  export async function runCompletionTypesPackage(
325
331
  global: GlobalOptions,
326
332
  ): Promise<{ types: string[]; count: number }> {
@@ -338,7 +344,7 @@ export async function runCompletionTypesPackage(
338
344
  };
339
345
  }
340
346
 
341
- /** Formats guide shell package output data for the selected output mode. */
347
+ /** Preserve script and word-list wire formats for canonical commands and compatibility aliases, with explicit JSON output retained. */
342
348
  export function renderGuideShellPackageOutput(
343
349
  context: ServiceOverrideContext,
344
350
  ): string | null {
@@ -349,13 +355,13 @@ export function renderGuideShellPackageOutput(
349
355
  if (context.command === "completion") {
350
356
  return renderCompletionPackageOutput(context.payload, result);
351
357
  }
352
- if (context.command === "completion-tags") {
358
+ if (context.command === "completion-tags" || context.command === "completion tags") {
353
359
  return renderJsonOrWords(context.payload, result, "tags");
354
360
  }
355
- if (context.command === "completion-statuses") {
361
+ if (context.command === "completion-statuses" || context.command === "completion statuses") {
356
362
  return renderJsonOrWords(context.payload, result, "statuses");
357
363
  }
358
- if (context.command === "completion-types") {
364
+ if (context.command === "completion-types" || context.command === "completion types") {
359
365
  return renderJsonOrWords(context.payload, result, "types");
360
366
  }
361
367
  return null;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-guide-shell",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for guide and shell completion workflows.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-kanban",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm archetype package: a complete Kanban continuous-flow profile built on public SDK primitives.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-lifecycle-hooks",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package demonstrating safe lifecycle hook registration.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-linked-test-adapters",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for optional linked-test run management adapters and reporters.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-search-advanced",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for semantic, hybrid, and reindex search workflows.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-templates",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for reusable create templates.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-todos",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for Todo markdown import and export.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-vcs-sdk-exemplar",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Beyond-PM exemplar: a VCS-style changeset workflow built entirely on public pm SDK and extension primitives.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pm-claude",
3
3
  "description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents (coordinator, delivery-chain, triage, verification), hybrid TUI task tracking (pm as persistent store + Claude Code task panel as live view), session context injection, and full git-based project management without leaving Claude Code.",
4
- "version": "2026.9.20",
4
+ "version": "2026.9.21",
5
5
  "author": {
6
6
  "name": "unbrained",
7
7
  "url": "https://github.com/unbraind/pm-cli"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pm-codex",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.21",
4
4
  "description": "Native Codex integration for pm-cli with bundled MCP tools, skills, commands, and agent workflows.",
5
5
  "author": {
6
6
  "name": "unbrained",