@unbrained/pm-cli 2026.11.1 → 2026.11.3
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +32 -0
- package/CONTRIBUTING.md +1 -1
- package/dist/cli/error-guidance.d.ts +9 -0
- package/dist/cli/error-guidance.js +4 -3
- package/dist/cli/main.js +1 -1
- package/dist/cli/migration-gates.js +1 -1
- package/dist/cli/runtime/field-route-retry.d.ts +15 -0
- package/dist/cli/runtime/field-route-retry.js +2 -0
- package/dist/cli-bundle/bundle-manifest.json +1 -1
- package/dist/cli-bundle/chunks/{chunk-2GK2IVU5.js → chunk-2CBHQXYJ.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-32BCU6HN.js +115 -0
- package/dist/cli-bundle/chunks/{chunk-MTRIGD7M.js → chunk-5IPXDZKU.js} +42 -42
- package/dist/cli-bundle/chunks/{chunk-O56O7NIE.js → chunk-5JZMF4M5.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TYERATXH.js → chunk-7ZEFHFAU.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-B6UTLYLM.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-N45IXPCA.js → chunk-DEJHTFEF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ICT6E4IW.js → chunk-HBKD5HZB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-6PKWKVS6.js → chunk-JPKIUWLG.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-WFBYKDB2.js → chunk-L6LCLC37.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Y7CKVU56.js → chunk-MQJXZX3Q.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-NR4KABHC.js +31 -0
- package/dist/cli-bundle/chunks/{chunk-WX25MU4N.js → chunk-O4ZLEN4T.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-F3ECOBKA.js → chunk-PWD5RY2D.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SBVX5CMV.js → chunk-RSAN2YUU.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NILQ2ZMV.js → chunk-TZ3D3DPQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-MRUA2Z43.js → chunk-UJMQP2HP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TMPO4CTZ.js → chunk-UYNMKUGA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UUN3WNMQ.js → chunk-XRMYA4R7.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UEEG47TU.js → chunk-Y7H55PCY.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-5KW4WUAK.js → chunk-YWS4XV4I.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-ZOAJNPBL.js +129 -0
- package/dist/cli-bundle/chunks/{indexed-receipt-blobs-KGMJVFH2.js → indexed-receipt-blobs-I6RQGD6Y.js} +2 -2
- package/dist/cli-bundle/chunks/item-transaction-ZHLJTBD7.js +2 -0
- package/dist/cli-bundle/chunks/{mutation-admission-BOOCJPCU.js → mutation-admission-ZQMRMGIB.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-23OX36Q3.js → register-list-query-I6AZA3IX.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-JPJ5YNDX.js → register-mutation-3DAXCLXR.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-IGR7ERY5.js → register-operations-G3QGGQ5Z.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-BMIFKZZP.js → register-setup-LDXHMNOT.js} +2 -2
- package/dist/cli-bundle/chunks/{settlement-hook-YWSWFOZY.js → settlement-hook-JHXLUBEN.js} +2 -2
- package/dist/cli-bundle/chunks/{stage-ON7CYYPM.js → stage-7H36OTDJ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3XGKBVJ3.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-WX2RVS2Y.js → chunk-4HY6EGPB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-3NYWMUX3.js → chunk-D4XQOMG4.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-UQIBGLDR.js → chunk-F3X6UWMI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-JLXGRDTG.js → chunk-G6ERMFJ5.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-VFQAZLKO.js → chunk-HJ27QLZV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5TWS5KOM.js → chunk-HOXIIZEO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-HUXZCPWT.js +26 -0
- package/dist/cli-bundle/focused-chunks/{chunk-LVA76N27.js → chunk-I5FODKYB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-DFUTCKUF.js → chunk-IDAYTYNN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-2Y77HWIX.js → chunk-IKXJ57XA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RPUDOJVB.js → chunk-LKN2WGGB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-MOY6KZGJ.js +44 -0
- package/dist/cli-bundle/focused-chunks/{chunk-PAT6QF63.js → chunk-PWUTFKSI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-PZRB7IXH.js +91 -0
- package/dist/cli-bundle/focused-chunks/chunk-RY4QEMAE.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-6GMYW42K.js → chunk-TYHDZUL4.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-WSYPVBKS.js +80 -0
- package/dist/cli-bundle/focused-chunks/{chunk-Z7GIVH6B.js → chunk-WXLG7HZ5.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5WCQFH6D.js → chunk-WZDFCVLX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-VS2ZFPXD.js → chunk-YGO3FWA2.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-YVLAP3BL.js +23 -0
- package/dist/cli-bundle/focused-chunks/{chunk-6OKPYCLU.js → chunk-ZQRCVRGS.js} +54 -54
- package/dist/cli-bundle/focused-chunks/chunk-ZYXQACPB.js +2 -0
- package/dist/cli-bundle/focused-chunks/{indexed-receipt-blobs-KHWT44EK.js → indexed-receipt-blobs-7XGVHYAO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{item-transaction-7VLPA2SU.js → item-transaction-PZ2FQ6B2.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{mutation-admission-2DH27R5Y.js → mutation-admission-XOOK6XFH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{settlement-hook-SJV52ZTV.js → settlement-hook-H56537UV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{stage-FYOBWQA7.js → stage-4SQHVI3O.js} +2 -2
- package/dist/cli-bundle/main.js +30 -29
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +1 -1
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +57 -57
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +11 -11
- package/dist/core/extensions/extension-hook-runtime.js +1 -1
- package/dist/core/extensions/extension-types.d.ts +5 -0
- package/dist/core/extensions/extension-types.js +1 -1
- package/dist/core/extensions/item-fields.d.ts +1 -1
- package/dist/core/extensions/item-fields.js +1 -1
- package/dist/core/item/parse.js +2 -2
- package/dist/core/lock/lock-confinement.d.ts +55 -0
- package/dist/core/lock/lock-confinement.js +2 -0
- package/dist/core/lock/lock-gc.js +1 -1
- package/dist/core/lock/lock.js +2 -2
- package/dist/core/schema/runtime-field-values.d.ts +30 -0
- package/dist/core/schema/runtime-field-values.js +1 -1
- package/dist/core/sentry/helpers.js +1 -1
- package/dist/core/sentry/instrument.js +1 -1
- package/dist/core/shared/error-details.d.ts +98 -0
- package/dist/core/shared/error-details.js +2 -0
- package/dist/core/shared/errors.d.ts +43 -0
- package/dist/core/shared/errors.js +1 -1
- package/dist/core/store/settings-sections.d.ts +61 -0
- package/dist/core/store/settings-sections.js +3 -0
- package/dist/core/store/settings-validator.d.ts +4 -0
- package/dist/core/store/settings-validator.js +1 -1
- package/dist/core/store/settings.d.ts +29 -2
- package/dist/core/store/settings.js +4 -3
- package/dist/core/telemetry/consent.js +2 -2
- package/dist/core/telemetry/runtime.js +2 -2
- package/dist/core/test/background-runs.js +3 -3
- package/dist/mcp/server.js +2 -2
- package/dist/sdk/config.js +1 -1
- package/dist/sdk/errors.d.ts +6 -2
- package/dist/sdk/errors.js +1 -1
- package/dist/sdk/extension-command-context.js +2 -2
- package/dist/sdk/generated/error-code-catalog-rows.d.ts +39 -0
- package/dist/sdk/generated/error-code-catalog-rows.js +2 -0
- package/dist/sdk/generated/generated-error-code-catalog-part-1.d.ts +3 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-2.d.ts +3 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/generated-error-code-catalog.js +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/lifecycle/core-field-recovery.d.ts +26 -0
- package/dist/sdk/lifecycle/core-field-recovery.js +1 -1
- package/dist/sdk/lifecycle/create.js +1 -1
- package/dist/sdk/lifecycle/update.js +2 -2
- package/dist/sdk/mcp/discovery.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/runtime-primitives.d.ts +2 -1
- package/dist/sdk/runtime-primitives.js +1 -1
- package/dist/sdk/runtime.d.ts +1 -1
- package/dist/sdk/runtime.js +1 -1
- package/dist/sdk/test/entry.d.ts +5 -0
- package/dist/sdk/test/entry.js +2 -2
- package/dist/sdk/test/execution.d.ts +1 -2
- package/dist/sdk/test/execution.js +2 -2
- package/dist/sdk/test/linked-command-detection.d.ts +10 -0
- package/dist/sdk/test/linked-command-detection.js +1 -1
- package/dist/sdk/test/update.d.ts +2 -0
- package/dist/sdk/test/update.js +1 -1
- package/docs/AGENT_EVIDENCE_CONSISTENCY.md +10 -0
- package/docs/CONFIGURATION.md +9 -0
- package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +9 -6
- package/docs/EXTENSIONS.md +2 -2
- package/docs/LINKED_TEST_EDITS.md +38 -5
- package/docs/RELEASING.md +22 -2
- package/docs/SDK.md +103 -1
- package/docs/SDK_CONFIGURATION_SAFETY.md +55 -0
- package/docs/TESTING.md +2 -1
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +15 -3
- package/marketplace.json +1 -1
- package/package.json +9 -3
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/package.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +1 -1
- package/plugins/pm-codex/plugin.json +1 -1
- package/runtime-dependencies.json +1 -1
- package/dist/cli-bundle/chunks/chunk-5WVE7XBS.js +0 -114
- package/dist/cli-bundle/chunks/chunk-E74BORFX.js +0 -128
- package/dist/cli-bundle/chunks/chunk-MP2DQJH2.js +0 -3
- package/dist/cli-bundle/chunks/chunk-O6TFUV6M.js +0 -31
- package/dist/cli-bundle/chunks/item-transaction-Q5S5YLEJ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-3Z53POXU.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-7WJDRZOR.js +0 -22
- package/dist/cli-bundle/focused-chunks/chunk-AL7SOFUL.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-CIQ6YWCW.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-GE755ODZ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-JCR32IAO.js +0 -91
- package/dist/cli-bundle/focused-chunks/chunk-M22TI7LP.js +0 -79
- package/dist/cli-bundle/focused-chunks/chunk-SXZM4PSS.js +0 -44
package/docs/EXTENSIONS.md
CHANGED
|
@@ -306,7 +306,7 @@ Use the public SDK barrel. Do not deep-import from `src/core` or `dist/core`.
|
|
|
306
306
|
- `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.
|
|
307
307
|
- `api.registerCommand(definition)` adds package-owned commands; `read_output` opts readers into the [SDK output contract](SDK.md#minimal-command-extension).
|
|
308
308
|
- `api.registerFlags(command, flags)` adds runtime command flags. A flag may declare `value_type` (canonical; the legacy `type` alias is honored only when `value_type` is absent), `list: true` to accumulate repeated/comma-joined values like core `--tags`, a `default` applied when the flag is omitted, and `value_validation: "strict"` to refuse malformed `number`/`boolean` tokens before the handler runs (the default `"coerce"` forwards the raw token). See [Flag Contracts](SDK.md#flag-contracts).
|
|
309
|
-
- `api.registerItemFields(fields)` adds custom metadata fields. Agents can set declared fields with repeatable `pm create --field name=value` and `pm update <id> --field name=value`; undeclared names are rejected. `SchemaFieldDefinition.type` is the same closed union used by `pm schema add-field`: `string | number | boolean | string_array | array | object`. Unsupported values fail at compile time for TypeScript authors and at activation for JavaScript packages, with a did-you-mean hint on typos. `string_array` is the repeatable string collection; `array` and `object` require JSON containers. Active fields support `get`, `list` and `search` projections with `--fields name` or `--fields item.name`, preserving declared value types through `PmClient` and CLI reads. Disabled packages do not contribute selectors. Tracked by [pm-gh1571](../.agents/pm/issues/pm-gh1571.toon).
|
|
309
|
+
- `api.registerItemFields(fields)` adds custom metadata fields. Agents can set declared fields with repeatable `pm create --field name=value` and `pm update <id> --field name=value`; undeclared names are rejected. Extension declarations are matched first; a name that no active extension declares but the project schema does (for example `gate_evidence`) is refused with `project_schema_field_requires_declared_flag`, which names a CLI flag and an SDK option that each set only that field (each is omitted when every spelling is shared with another declared field or with an option of the command itself) and, on the CLI, an executable `suggested_retry_args` that rewrites only that assignment. The guidance follows the invoking scope (a bulk `update-many` row is routed under `update_many`, not `update`), and when the same invocation already sets that field through a declared flag, alias or option, no route or retry is offered, because the retry would carry two values for one field ([pm-wftvem](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-wftvem.toon); tracker record excluded from npm); reserved core keys keep `core_item_field_requires_dedicated_flag`. `SchemaFieldDefinition.type` is the same closed union used by `pm schema add-field`: `string | number | boolean | string_array | array | object`. Unsupported values fail at compile time for TypeScript authors and at activation for JavaScript packages, with a did-you-mean hint on typos. `string_array` is the repeatable string collection; `array` and `object` require JSON containers. Active fields support `get`, `list` and `search` projections with `--fields name` or `--fields item.name`, preserving declared value types through `PmClient` and CLI reads. Disabled packages do not contribute selectors. Tracked by [pm-gh1571](../.agents/pm/issues/pm-gh1571.toon).
|
|
310
310
|
- Custom fields whose camel-case option name is already owned by a canonical MCP input remain usable through `options.<name>`, but authoring surfaces report the collision instead of allowing silent top-level shadowing. `pm schema add-field`, `pm profile lint`, and `pm package doctor` name the field, canonical `mcp_tool_input` owner, and nested recovery path. SDK authors can preflight the same rule with `resolvePmToolCustomFieldCollision`.
|
|
311
311
|
- `api.registerItemTypes(types)` adds custom item types.
|
|
312
312
|
- `api.registerRelationshipKinds(definitions)` adds validated graph semantics. Definitions declare direction, inverse spelling, ordering/precedence, hierarchy, cardinality, lifecycle, aliases, payload schema, compatibility version, and self-edge policy. Active definitions govern CLI, MCP, and SDK dependency mutation admission as well as workspace graph assembly; mutation aliases are stored canonically. Requires the `schema` capability and is governed by the `schema.relationshipkinds` policy surface. See [relationship mutation admission](RELATIONSHIP_GRAPH.md#contract), tracked by [pm-7dsolo](../.agents/pm/issues/pm-7dsolo.toon).
|
|
@@ -426,7 +426,7 @@ import { createExtensionTestHarness } from "@unbrained/pm-cli/sdk/testing";
|
|
|
426
426
|
import { activateExtensionForTest } from "@unbrained/pm-cli/sdk/testing";
|
|
427
427
|
```
|
|
428
428
|
|
|
429
|
-
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.
|
|
429
|
+
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; those bounds never split a surrogate pair. Put structured, package-owned facts in `context.details` (plain JSON, at most 4,096 bytes when rendered) rather than spreading them over host fields. The host renders them in `--json`, text and MCP refusals and never sends them to telemetry or Sentry; see [Producer-owned diagnostics](SDK.md#producer-owned-diagnostics-contextdetails).
|
|
430
430
|
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`.
|
|
431
431
|
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)`.
|
|
432
432
|
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.
|
|
@@ -21,11 +21,44 @@ index and metadata field names in `context.linked_test_update`.
|
|
|
21
21
|
Use `null` to clear an optional field, such as a note, path or timeout. Scope is
|
|
22
22
|
required and cannot be cleared. Every entry must retain a nonblank command or path:
|
|
23
23
|
replace a path-only entry's path rather than clearing its last identity.
|
|
24
|
-
Unknown fields,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
Unknown fields, provenance changes and editor-stamp overrides are refused with
|
|
25
|
+
`linked_test_patch_fields_unsupported`, which lists the editable fields in
|
|
26
|
+
`recovery.allowed_values`. Editing context or environment controls changes the
|
|
27
|
+
clone-local trust fingerprint, so any prior acknowledgment must be reviewed again.
|
|
28
|
+
|
|
29
|
+
A command is the entry's immutable identity, so a `command` or `cmd` key is
|
|
30
|
+
refused with `linked_test_command_immutable` before anything is written. The
|
|
31
|
+
refusal's `recovery.suggested_retry_args` is the supported replacement
|
|
32
|
+
([pm-1rfy0y](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-1rfy0y.toon);
|
|
33
|
+
tracker record excluded from npm): one `pm test` invocation
|
|
34
|
+
that removes the selected entry (by its exact command, or by its locked position
|
|
35
|
+
when the entry has no unique command) and adds the new command with the entry's
|
|
36
|
+
other metadata and any other fields from your patch. The replacement records
|
|
37
|
+
fresh provenance in a single `tests_add` history event, leaves every other entry
|
|
38
|
+
untouched, and is appended at the end of the list:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pm test <item-id> --update-index 1 --set-json '{"command":"node scripts/check-v2.mjs"}' --json
|
|
42
|
+
# refused: linked_test_command_immutable; run the advertised retry, for example
|
|
43
|
+
pm test <item-id> --remove 'command=node scripts/check.mjs' --add-json '{"command":"node scripts/check-v2.mjs","scope":"project","note":"Verified coverage gate"}'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Repeating the current command, or sending an empty one, is refused with the same
|
|
47
|
+
code and a pointer to the editable fields instead of a replacement. Other fields
|
|
48
|
+
in the same patch are validated before the retry is offered, so an unsupported
|
|
49
|
+
key, `scope: null` or an invalid value refuses instead of being silently dropped.
|
|
50
|
+
When the replacement would have the same identity (command, path, scope and
|
|
51
|
+
context modes) as another entry, the add would be deduplicated away, so no retry
|
|
52
|
+
is offered; the refusal names that entry's `--update-index` and the selected
|
|
53
|
+
entry's `--remove-index` instead. Conflicting `command` and `cmd` values, and a
|
|
54
|
+
replacement that would invoke `pm test-all`, refuse without a retry. Explicit
|
|
55
|
+
`--author`, `--message` and `--force` on the refused edit are carried into the
|
|
56
|
+
retry, so ownership and history attribution match the original request.
|
|
57
|
+
The retry is a separate mutation: if other writers may change the item's tests
|
|
58
|
+
in between, list them again before running it. An atomic replacement under one
|
|
59
|
+
item lock is tracked by
|
|
60
|
+
[pm-5igljl](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-5igljl.toon)
|
|
61
|
+
(tracker record excluded from npm).
|
|
29
62
|
|
|
30
63
|
Exactly one selector must match the current collection under the item lock.
|
|
31
64
|
Absent selectors and ambiguous command/path matches refuse the whole edit and
|
package/docs/RELEASING.md
CHANGED
|
@@ -317,8 +317,18 @@ installed-version verification. [pm-iceees](../.agents/pm/issues/pm-iceees.toon)
|
|
|
317
317
|
keeps selected optional-peer subtrees complete: npm deliberately skips peer edges
|
|
318
318
|
when gathering bundled files, so staged runtime manifests record the exact tested
|
|
319
319
|
peer bindings as ordinary or optional dependency entries. Package code, source
|
|
320
|
-
and installed manifests, peer declarations
|
|
321
|
-
|
|
320
|
+
and installed manifests, and peer declarations remain intact.
|
|
321
|
+
[pm-2csj4k](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-2csj4k.toon) (repository-only tracker record excluded from npm) adds one root entry per required
|
|
322
|
+
peer: Bun installs resolve a package's dependencies from the registry instead of
|
|
323
|
+
its `bundleDependencies`, so the published root manifest pins every non-optional
|
|
324
|
+
peer target that the ledger installs at the root to its tested version and
|
|
325
|
+
bundles it. A peer resolved only in a nested `node_modules` is not pinned,
|
|
326
|
+
because the root manifest may name only root-installed packages, which the
|
|
327
|
+
installed-runtime verifier enforces. Without the pin,
|
|
328
|
+
`@sentry/node`'s `@opentelemetry/api ^1.9.1` resolved to 1.10.0 and Bun warned
|
|
329
|
+
against the bundled OpenTelemetry packages' `<1.10.0` peer ranges. Optional-only
|
|
330
|
+
peers and direct dependencies are unchanged, and the packed smoke runs a verbose
|
|
331
|
+
`bun add` and fails on any peer-range warning. A real archive regression resolves the peer's descendant
|
|
322
332
|
from an extracted package and the installed-runtime verifier still refuses any
|
|
323
333
|
missing locked package. npm 12 ignores published shrinkwraps; shipping
|
|
324
334
|
a shrinkwrap alone therefore cannot enforce this contract. SDK consumers
|
|
@@ -467,6 +477,16 @@ contents, comments, JSDoc, symbols and module boundaries retain their original
|
|
|
467
477
|
tokens. Source declarations remain readable, and packed TypeScript consumers
|
|
468
478
|
verify the emitted surface before publication. Artifact ceilings remain unchanged.
|
|
469
479
|
|
|
480
|
+
The generated error-code catalog ships as compact rows
|
|
481
|
+
([pm-998juj](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/tasks/pm-998juj.toon), a repository-only tracker record excluded from npm).
|
|
482
|
+
`scripts/generate-error-code-catalog.mjs` omits every derivable field: the
|
|
483
|
+
meaning sentence, the class implied by the exit code, the shared recovery
|
|
484
|
+
guidance, provisional stability, every-command emitters, a self canonical code
|
|
485
|
+
and empty aliases. `expandPmErrorCodeCatalogRows` restores them at load time,
|
|
486
|
+
so `PM_ERROR_CODE_CATALOG` and every serialized projection stay byte-identical.
|
|
487
|
+
The catalog appears once in the tsc emit and once in each CLI bundle, and the
|
|
488
|
+
compact rows removed about 320 KB from the packed distribution.
|
|
489
|
+
|
|
470
490
|
5. Land the implementation through a reviewed pull request, then use hosted
|
|
471
491
|
preparation for publication.
|
|
472
492
|
|
package/docs/SDK.md
CHANGED
|
@@ -328,6 +328,32 @@ try {
|
|
|
328
328
|
}
|
|
329
329
|
```
|
|
330
330
|
|
|
331
|
+
Locks are confined to the tracker
|
|
332
|
+
([pm-gh1647](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1647.toon),
|
|
333
|
+
a repository-only tracker record excluded from npm). The built-in provider
|
|
334
|
+
never follows a symlink below the tracker root. If `locks/` or any other
|
|
335
|
+
component between the tracker root and the lock entry is a symlink or not a
|
|
336
|
+
directory, or the lock entry itself is a symlink, `acquireLock` and
|
|
337
|
+
`acquireLockLease` refuse with `lock_path_unsafe` (exit 4). A regular-file lock
|
|
338
|
+
entry is a peer's lock, not a refusal. The refusal carries `context.reason`
|
|
339
|
+
(`lock_directory_symlink`, `lock_directory_not_directory`,
|
|
340
|
+
`lock_entry_symlink` or `lock_path_outside_tracker`), the tracker-relative
|
|
341
|
+
`context.lock_component`, and `context.required` recovery text for that reason.
|
|
342
|
+
For these four reasons nothing is created outside the tracker and no cleanup
|
|
343
|
+
gate remains. After creating the lock file, the provider checks that the new
|
|
344
|
+
file is the confined entry in the directory it inspected. A directory swapped
|
|
345
|
+
during acquisition refuses with the same `lock_path_unsafe` code and the
|
|
346
|
+
fifth reason, `lock_directory_replaced`, with `context.lock_component` naming
|
|
347
|
+
the replaced tracker-relative directory, and the lease is never returned.
|
|
348
|
+
The lock file created through the swapped directory stays where the swap
|
|
349
|
+
pointed, which can be outside the tracker, and a cleanup gate
|
|
350
|
+
created before the swap can stay in the displaced directory. pm never deletes
|
|
351
|
+
outside the tracker: Node has no descriptor-relative unlink, so a path-based
|
|
352
|
+
delete could remove a same-name replacement. `pm gc --scope locks`
|
|
353
|
+
applies the same check and refuses to sweep through a symlinked `locks/`
|
|
354
|
+
directory. The tracker root itself may be a symlink: confinement is relative to
|
|
355
|
+
the root you pass.
|
|
356
|
+
|
|
331
357
|
See
|
|
332
358
|
[Configuration](CONFIGURATION.md#common-settings) for host identity, local
|
|
333
359
|
recovery audit receipts and `PM_LOCK_WAIT_MS` precedence. Extension lock
|
|
@@ -657,7 +683,8 @@ for policies, work ceilings and refusal contracts, tracked by
|
|
|
657
683
|
Session receipts now advertise `pm get <item-id> --depth brief`; the
|
|
658
684
|
`restore_reference_with` literal type changes accordingly. Hosts constructing
|
|
659
685
|
`ExtensionCommandSdk` implementations must supply `fitOutputEnvelope` from the
|
|
660
|
-
public SDK
|
|
686
|
+
public SDK, plus `readSettingsSection` and `writeSettingsSection` bound to the
|
|
687
|
+
invocation tracker; host-created command contexts already provide all three.
|
|
661
688
|
|
|
662
689
|
Tracked by [pm-5t33or](../.agents/pm/features/pm-5t33or.toon),
|
|
663
690
|
[pm-gmdzaa](../.agents/pm/issues/pm-gmdzaa.toon), and
|
|
@@ -3102,6 +3129,81 @@ propagates `code` and `remediation` through the command-handler result contract.
|
|
|
3102
3129
|
Invalid `exit_code` values are rejected rather than truncated or silently
|
|
3103
3130
|
treated as success.
|
|
3104
3131
|
|
|
3132
|
+
### Producer-owned diagnostics (`context.details`)
|
|
3133
|
+
|
|
3134
|
+
Tracked by [pm-gh1631](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1631.toon)
|
|
3135
|
+
(tracker record excluded from npm). Host fields such as `code`, `required` and
|
|
3136
|
+
`recovery` describe the refusal in the host's own vocabulary. Facts that belong
|
|
3137
|
+
to the package go in `context.details`, a plain JSON object the host never
|
|
3138
|
+
interprets:
|
|
3139
|
+
|
|
3140
|
+
```ts
|
|
3141
|
+
import { createPmCliExpectedError } from "@unbrained/pm-cli/sdk/runtime";
|
|
3142
|
+
|
|
3143
|
+
throw createPmCliExpectedError("No changelog section for 2026.11.1", {
|
|
3144
|
+
exitCode: 1,
|
|
3145
|
+
context: {
|
|
3146
|
+
code: "release_notes_missing",
|
|
3147
|
+
details: {
|
|
3148
|
+
selection_report: { filters: { version: "2026.11.1" }, excluded: { status: 1 } },
|
|
3149
|
+
},
|
|
3150
|
+
},
|
|
3151
|
+
});
|
|
3152
|
+
```
|
|
3153
|
+
|
|
3154
|
+
- **Shape.** Values are `null`, booleans, finite numbers, well-formed strings,
|
|
3155
|
+
arrays and plain objects, nested at most `PM_CLI_ERROR_DETAILS_LIMITS.max_depth`
|
|
3156
|
+
(8) containers deep. `__proto__` keys and accessor properties are refused;
|
|
3157
|
+
getters are never run. `createPmCliExpectedError` throws a `TypeError` whose
|
|
3158
|
+
message names only the reason (`unsupported_value`, `non_finite_number`,
|
|
3159
|
+
`malformed_unicode`, `reserved_key`, `depth_limit`, `not_plain_object`); the
|
|
3160
|
+
offending path is on its non-enumerable `path` property, so crash reporting
|
|
3161
|
+
of that fault never carries your keys. A well-formed value is kept as a
|
|
3162
|
+
detached copy, so later changes to your object do not alter a raised
|
|
3163
|
+
refusal; an oversized one is replaced at construction by the host-set
|
|
3164
|
+
receipt `context.details_omitted: { reason: "byte_limit", byte_limit }`, so a
|
|
3165
|
+
later change cannot alter the refusal either. `isPmCliErrorDetails(value)`
|
|
3166
|
+
performs the same check.
|
|
3167
|
+
- **Rendering.** `--json` errors carry the object as `details`, text output
|
|
3168
|
+
renders it as an indented JSON `Details:` block, and MCP tool errors carry it
|
|
3169
|
+
inside the forwarded context. Diagnostics are rendered whole or not at all:
|
|
3170
|
+
above `PM_CLI_ERROR_DETAILS_LIMITS.max_bytes` (4,096 bytes of compact UTF-8
|
|
3171
|
+
JSON), or when a separately bundled error carries a malformed shape, the
|
|
3172
|
+
envelope carries `details_omitted: { reason, path?, byte_limit }` instead.
|
|
3173
|
+
Admitted details that would push the pretty-printed `--json` envelope past
|
|
3174
|
+
the error diagnostic budget are replaced the same way, with reason
|
|
3175
|
+
`diagnostic_budget`.
|
|
3176
|
+
The size is counted while walking and the walk stops at the ceiling, so
|
|
3177
|
+
shared or repeated structures cannot amplify the work; `path` is capped at
|
|
3178
|
+
160 bytes. The CLI and MCP read a separately bundled error's context once as
|
|
3179
|
+
plain data (`snapshotPmCliErrorContext`): getters are never run, and a
|
|
3180
|
+
context that cannot be inspected becomes empty. MCP admits `details` from that
|
|
3181
|
+
snapshot with the same bounded walk before serializing anything, then
|
|
3182
|
+
serializes the remaining host fields once (a context-level `toJSON` is
|
|
3183
|
+
ignored), so no serializer can expand or replace the diagnostics; a context
|
|
3184
|
+
JSON cannot encode (for example a bigint member) is forwarded as
|
|
3185
|
+
`{ code, context_unserializable: true }` so the response is still written. When the text output exceeds its token ceiling, the
|
|
3186
|
+
text renderer drops the explanation (`why`) first and then the `Details:`
|
|
3187
|
+
block (together with the example and next-step limits). A block dropped this
|
|
3188
|
+
way gets no `Details omitted:` line, only the generic notice that points to
|
|
3189
|
+
`--json`, which keeps the details. Custom SDK hosts apply the
|
|
3190
|
+
same bound with `projectPmCliErrorDetails(value)` (returns `{ details }`,
|
|
3191
|
+
`{ details_omitted }` or `undefined`) or, for a context forwarded as-is,
|
|
3192
|
+
`projectPmCliErrorContextDetails(context)`.
|
|
3193
|
+
- **Privacy.** Telemetry and Sentry never receive `details`. The telemetry
|
|
3194
|
+
classification is built without it. A crash report carries an error
|
|
3195
|
+
context only as its top-level primitive fields, read without running
|
|
3196
|
+
getters or `toJSON`, so diagnostics cannot reach it under another key: this
|
|
3197
|
+
applies to `error_context` and to the error-data entry, which is rebuilt
|
|
3198
|
+
whole from the original exception (its own primitive fields plus the safe
|
|
3199
|
+
context), because the integration serializes the error, including any
|
|
3200
|
+
error-level `toJSON`, before `beforeSend`. Serialized copies whose original
|
|
3201
|
+
cannot be recovered are discarded: embedded contexts in console-capture
|
|
3202
|
+
data, breadcrumbs and transactions are sent as empty objects, and complete
|
|
3203
|
+
serialized console `arguments` are sent as empty arrays, because an error's
|
|
3204
|
+
own `toJSON` can move diagnostics out of any named slot. The custom-host
|
|
3205
|
+
projections drop a context-level `toJSON` for the same reason.
|
|
3206
|
+
|
|
3105
3207
|
## Package Runtime Imports
|
|
3106
3208
|
|
|
3107
3209
|
Third-party packages should import from stable public SDK subpaths:
|
|
@@ -46,6 +46,61 @@ and reconstructed in the preview. File-backed schema overlays and unknown raw
|
|
|
46
46
|
keys are outside this normalized preview. Inspect the persisted document when
|
|
47
47
|
raw-source information is needed.
|
|
48
48
|
|
|
49
|
+
## Extension-owned Settings Sections
|
|
50
|
+
|
|
51
|
+
Tracked by [pm-gh1580](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1580.toon)
|
|
52
|
+
(a repository-only tracker record excluded from npm).
|
|
53
|
+
|
|
54
|
+
Core settings readers validate the core tree and strip keys they do not own.
|
|
55
|
+
That includes a package's own top-level section, such as `"lint": {...}`.
|
|
56
|
+
Read and write that section through the host instead of re-reading
|
|
57
|
+
`settings.json` by path:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const lint = await context.sdk!.readSettingsSection("lint", {
|
|
61
|
+
validate: (raw) => lintSettingsSchema.parse(raw),
|
|
62
|
+
defaultValue: { strict: false },
|
|
63
|
+
});
|
|
64
|
+
// lint.source: "stored" | "default"; lint.value; lint.revision ("sha256:<hex>" or null)
|
|
65
|
+
|
|
66
|
+
await context.sdk!.writeSettingsSection("lint", { ...lint.value, strict: true }, {
|
|
67
|
+
expectedRevision: lint.revision,
|
|
68
|
+
validate: (raw) => lintSettingsSchema.parse(raw),
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The same functions are public SDK exports (`readSettingsSection(pmRoot, section,
|
|
73
|
+
options)`, `writeSettingsSection(pmRoot, section, value, options)` and
|
|
74
|
+
`settingsSectionRevision(value)` from `@unbrained/pm-cli/sdk`). The
|
|
75
|
+
`context.sdk` variants are bound to the invocation's tracker.
|
|
76
|
+
|
|
77
|
+
- A section name is 1-64 lowercase letters, digits, underscores or hyphens,
|
|
78
|
+
starting with a letter. Any other name refuses with
|
|
79
|
+
`settings_section_name_invalid`. Core keys such as `locks` or `context`
|
|
80
|
+
refuse with `settings_section_reserved`; use `writeSettings`, `pm config` or
|
|
81
|
+
`mutateWorkspaceSettings` for those.
|
|
82
|
+
- If settings.json is not a JSON object, the call refuses with
|
|
83
|
+
`settings_section_document_malformed` instead of throwing a parse error.
|
|
84
|
+
- If the validator throws, the call refuses with `settings_section_invalid`.
|
|
85
|
+
`context.field` names the section, and the message carries the validator's
|
|
86
|
+
bounded message. Reads validate the stored value; writes validate the value
|
|
87
|
+
before storing it. A write also refuses with `settings_section_invalid` when
|
|
88
|
+
the value would change if stored as JSON: a non-finite number, an
|
|
89
|
+
`undefined`, function or symbol value, a symbol key, or a non-plain object
|
|
90
|
+
such as `Date`, including an array with holes, extra keys or a `toJSON`
|
|
91
|
+
hook. A key named `__proto__`, or `prototype` beneath `constructor`, also
|
|
92
|
+
refuses because the settings history cannot record it. The message names the
|
|
93
|
+
first such path, and nothing is written.
|
|
94
|
+
- A write runs under the settings lock and appends one `settings:section:write`
|
|
95
|
+
workspace history event. Every other key is kept. Pass `undefined` to remove
|
|
96
|
+
the section. An unchanged value writes nothing and returns `changed: false`.
|
|
97
|
+
- `expectedRevision` makes the write compare-and-set. `null` requires the section
|
|
98
|
+
to be absent. If the section changed since it was read, the write refuses with
|
|
99
|
+
`settings_section_revision_conflict` (exit 4) and records
|
|
100
|
+
`context.expected_revision` and `context.current_revision`. If settings.json
|
|
101
|
+
does not exist, the write refuses with `settings_section_document_missing`
|
|
102
|
+
(exit 3); initialize the tracker first.
|
|
103
|
+
|
|
49
104
|
## Read-only Package Freshness
|
|
50
105
|
|
|
51
106
|
`pm package explore`, `doctor`, and `manage` preserve managed installation state.
|
package/docs/TESTING.md
CHANGED
|
@@ -332,7 +332,7 @@ original assertions, deadlines and retry policy. This allocation is tracked by
|
|
|
332
332
|
(tracker records are excluded from npm); it does not classify or erase
|
|
333
333
|
historical failed attempts.
|
|
334
334
|
|
|
335
|
-
The complete nightly suites use two Vitest shards on Linux Node 22/
|
|
335
|
+
The complete nightly suites use two Vitest shards on Linux Node 22/26 and
|
|
336
336
|
macOS Node 24, and four shards on Windows Node 24 and Linux Node 24 coverage.
|
|
337
337
|
Every partition must pass within the existing 20-minute job limit. Sharding
|
|
338
338
|
retains the complete file population, serial phase, assertions, per-test
|
|
@@ -368,6 +368,7 @@ Coverage gating now targets literal all-source coverage across runtime code fami
|
|
|
368
368
|
- Avoid reintroducing curated coverage allowlists; keep the full all-source corpus measurable and gated.
|
|
369
369
|
- Prefer extending existing test files and shared helpers so new coverage remains fast and non-duplicative.
|
|
370
370
|
- Prefer extracting deterministic pure helpers (and unit-testing them) when an orchestration-heavy file is difficult to cover directly.
|
|
371
|
+
- Vitest 5 clears every mock's recorded calls before each test (`clearMocks` defaults to `true`; [pm-fokyhh](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/chores/pm-fokyhh.toon), a repository-only tracker record excluded from npm). A spy created in `vi.hoisted` that observes work done while the module under test is imported must record into its own array, as the SDK exemplar entry specs do; `mock.calls` is empty by the time the test body runs.
|
|
371
372
|
|
|
372
373
|
Static quality also enforces source documentation coverage through `pnpm
|
|
373
374
|
quality:static`: every `src/**/*.ts` source file needs a module TSDoc block,
|
|
@@ -4,12 +4,12 @@ Tracker: `pm-f05lsg`.
|
|
|
4
4
|
|
|
5
5
|
Every catalog code is listed. An `uncovered` row is an explicit closure obligation, never an omission or implied approval.
|
|
6
6
|
|
|
7
|
-
- Catalog error codes:
|
|
7
|
+
- Catalog error codes: 446
|
|
8
8
|
- Executable error codes: 19
|
|
9
9
|
- Executable-code ratchet floor: 18
|
|
10
10
|
- Required executable canonical codes: `bulk_ids_input_empty`, `bulk_ids_input_missing_path`, `bulk_ids_input_unreadable`, `invalid_argument_value`, `manifest_unknown_key`, `missing_lifecycle_target`, `missing_required_argument`, `no_version_bounds_declared`, `projection_options_mutually_exclusive`, `tracker_not_initialized`, `tracker_root_missing`, `tracker_root_not_directory`, `tracker_root_unreadable`, `unknown_context_intent`, `unknown_field_projection`, `unknown_option`, `unknown_subcommand`
|
|
11
|
-
- Uncovered error codes:
|
|
12
|
-
- Coverage fraction: 0.
|
|
11
|
+
- Uncovered error codes: 427
|
|
12
|
+
- Coverage fraction: 0.042601
|
|
13
13
|
- Closed-domain probes: 19
|
|
14
14
|
- Grammar probes: 117
|
|
15
15
|
|
|
@@ -194,8 +194,10 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
194
194
|
| `likely_duplicate` | `likely_duplicate` | uncovered | none | 0 |
|
|
195
195
|
| `linked_artifact_mutation_conflict` | `linked_artifact_mutation_conflict` | uncovered | none | 0 |
|
|
196
196
|
| `linked_resource_positional_value` | `linked_resource_positional_value` | uncovered | none | 0 |
|
|
197
|
+
| `linked_test_command_immutable` | `linked_test_command_immutable` | uncovered | none | 0 |
|
|
197
198
|
| `linked_test_command_not_executable` | `linked_test_command_not_executable` | uncovered | none | 0 |
|
|
198
199
|
| `linked_test_context_invalid` | `linked_test_context_invalid` | uncovered | none | 0 |
|
|
200
|
+
| `linked_test_patch_fields_unsupported` | `linked_test_patch_fields_unsupported` | uncovered | none | 0 |
|
|
199
201
|
| `linked_test_remove_no_match` | `linked_test_remove_no_match` | uncovered | none | 0 |
|
|
200
202
|
| `linked_test_update_ambiguous` | `linked_test_update_ambiguous` | uncovered | none | 0 |
|
|
201
203
|
| `linked_test_update_no_match` | `linked_test_update_no_match` | uncovered | none | 0 |
|
|
@@ -205,6 +207,7 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
205
207
|
| `local_source_not_found_bare_name` | `local_source_not_found_bare_name` | uncovered | none | 0 |
|
|
206
208
|
| `lock_conflict` | `lock_conflict` | uncovered | none | 0 |
|
|
207
209
|
| `lock_lost` | `lock_lost` | uncovered | none | 0 |
|
|
210
|
+
| `lock_path_unsafe` | `lock_path_unsafe` | uncovered | none | 0 |
|
|
208
211
|
| `locks_stale_count` | `locks_stale_count` | uncovered | none | 0 |
|
|
209
212
|
| `locks_unreadable` | `locks_unreadable` | uncovered | none | 0 |
|
|
210
213
|
| `malformed_plan_step_evidence` | `malformed_plan_step_evidence` | uncovered | none | 0 |
|
|
@@ -282,6 +285,7 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
282
285
|
| `project_runtime_item_format_incompatible` | `project_runtime_item_format_incompatible` | uncovered | none | 0 |
|
|
283
286
|
| `project_runtime_stale_mutation` | `project_runtime_stale_mutation` | uncovered | none | 0 |
|
|
284
287
|
| `project_runtime_stale_read` | `project_runtime_stale_read` | uncovered | none | 0 |
|
|
288
|
+
| `project_schema_field_requires_declared_flag` | `project_schema_field_requires_declared_flag` | uncovered | none | 0 |
|
|
285
289
|
| `projection_options_mutually_exclusive` | `projection_options_mutually_exclusive` | executable | closed_domain | 3 |
|
|
286
290
|
| `provenance_value_domain_invalid` | `provenance_value_domain_invalid` | uncovered | none | 0 |
|
|
287
291
|
| `read_output_cursor_command_mismatch` | `read_output_cursor_command_mismatch` | uncovered | none | 0 |
|
|
@@ -312,8 +316,16 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
312
316
|
| `settings_read_invalid_json` | `settings_read_invalid_json` | uncovered | none | 0 |
|
|
313
317
|
| `settings_read_invalid_schema` | `settings_read_invalid_schema` | uncovered | none | 0 |
|
|
314
318
|
| `settings_read_merge_failed` | `settings_read_merge_failed` | uncovered | none | 0 |
|
|
319
|
+
| `settings_section_document_malformed` | `settings_section_document_malformed` | uncovered | none | 0 |
|
|
320
|
+
| `settings_section_document_missing` | `settings_section_document_missing` | uncovered | none | 0 |
|
|
321
|
+
| `settings_section_invalid` | `settings_section_invalid` | uncovered | none | 0 |
|
|
322
|
+
| `settings_section_name_invalid` | `settings_section_name_invalid` | uncovered | none | 0 |
|
|
323
|
+
| `settings_section_reserved` | `settings_section_reserved` | uncovered | none | 0 |
|
|
324
|
+
| `settings_section_revision_conflict` | `settings_section_revision_conflict` | uncovered | none | 0 |
|
|
315
325
|
| `settings_unreadable` | `settings_unreadable` | uncovered | none | 0 |
|
|
326
|
+
| `settings_write_assigned_path_invalid` | `settings_write_assigned_path_invalid` | uncovered | none | 0 |
|
|
316
327
|
| `settings_write_invalid_existing_json` | `settings_write_invalid_existing_json` | uncovered | none | 0 |
|
|
328
|
+
| `settings_write_invalid_existing_schema` | `settings_write_invalid_existing_schema` | uncovered | none | 0 |
|
|
317
329
|
| `stale_budget` | `stale_budget` | uncovered | none | 0 |
|
|
318
330
|
| `stale_destination` | `stale_destination` | uncovered | none | 0 |
|
|
319
331
|
| `stale_observed_signature` | `stale_observed_signature` | uncovered | none | 0 |
|
package/marketplace.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"pm","owner":{"name":"unbrained","url":"https://github.com/unbraind/pm-cli"},"description":"Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.","version":"2026.11.
|
|
1
|
+
{"name":"pm","owner":{"name":"unbrained","url":"https://github.com/unbraind/pm-cli"},"description":"Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.","version":"2026.11.3","plugins":[{"name":"pm-claude","source":"./plugins/pm-claude","description":"Native pm CLI integration for Claude Code — 32 MCP tools, 14 workflow skills with slash invocations, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.","version":"2026.11.3","author":{"name":"unbrained","url":"https://github.com/unbraind/pm-cli"},"homepage":"https://github.com/unbraind/pm-cli","repository":"https://github.com/unbraind/pm-cli","license":"MIT","keywords":["pm-cli","project-management","mcp","tasks","agents","workflows","git-native","task-tracker","ai"],"category":"productivity"}]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-cli",
|
|
3
|
-
"version": "2026.11.
|
|
3
|
+
"version": "2026.11.3",
|
|
4
4
|
"description": "Git-native project management CLI for humans and agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.28.5",
|
|
@@ -137,7 +137,10 @@
|
|
|
137
137
|
"semver": "7.8.5",
|
|
138
138
|
"tar": "7.5.22",
|
|
139
139
|
"tinyglobby": "^0.2.17",
|
|
140
|
-
"yaml": "^2.9.1"
|
|
140
|
+
"yaml": "^2.9.1",
|
|
141
|
+
"@opentelemetry/api": "1.9.1",
|
|
142
|
+
"@opentelemetry/core": "2.12.0",
|
|
143
|
+
"@opentelemetry/sdk-trace-base": "2.12.0"
|
|
141
144
|
},
|
|
142
145
|
"peerDependencies": {
|
|
143
146
|
"@types/node": "^22 || ^24 || ^26"
|
|
@@ -156,6 +159,9 @@
|
|
|
156
159
|
"semver",
|
|
157
160
|
"tar",
|
|
158
161
|
"tinyglobby",
|
|
159
|
-
"yaml"
|
|
162
|
+
"yaml",
|
|
163
|
+
"@opentelemetry/api",
|
|
164
|
+
"@opentelemetry/core",
|
|
165
|
+
"@opentelemetry/sdk-trace-base"
|
|
160
166
|
]
|
|
161
167
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-beads","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-beads","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package for importing Beads JSONL records.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-beads#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-beads"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","beads"],"pm":{"aliases":["beads"],"extensions":["extensions/beads"],"catalog":{"display_name":"Beads Import","category":"migration","summary":"Import Beads JSONL records into pm while preserving source IDs.","tags":["migration","beads","import"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-beads#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-beads","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-calendar","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-calendar","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package for calendar and agenda views.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-calendar#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-calendar"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","calendar","agenda"],"pm":{"aliases":["calendar"],"extensions":["extensions/calendar"],"catalog":{"display_name":"Calendar Views","category":"workflow","summary":"Show agenda, day, week, and month views for deadlines, reminders, and scheduled events.","tags":["calendar","agenda","workflow"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-calendar#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-calendar","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-command-kit","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-command-kit","version":"2026.11.3","private":true,"type":"module","description":"First-party pm exemplar package for the commands capability: registerCommand, registerFlags, and registerParser.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-command-kit#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-command-kit"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","sdk","commands","exemplar"],"pm":{"aliases":["command-kit"],"extensions":["extensions/command-kit"],"catalog":{"display_name":"Command Kit Exemplar","category":"sdk","summary":"Copy-paste-able exemplar for registerCommand, registerFlags, and registerParser.","tags":["sdk","commands","parser","exemplar"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-command-kit#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-command-kit","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-digital-twin","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-digital-twin","version":"2026.11.3","private":true,"type":"module","description":"Beyond-PM exemplar: a temporal production-facility digital twin built entirely on public pm SDK and extension primitives.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-digital-twin#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-digital-twin"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","sdk","digital-twin","event-sourcing","temporal-graph","exemplar"],"pm":{"aliases":["digital-twin","twin"],"extensions":["extensions/digital-twin"],"catalog":{"display_name":"Digital Twin SDK Exemplar","category":"sdk","summary":"Temporal facility graph proving event replay, point-in-time state, invariants, federation, checkpoints, and compact exports through public SDK contracts.","tags":["sdk","digital-twin","event-sourcing","graph","offline-first","exemplar"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-digital-twin#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-digital-twin","report":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-digital-twin/GAP_REPORT.md"}},"docs":["README.md","GAP_REPORT.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-governance-audit","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-governance-audit","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package for governance audit and normalization workflows.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-governance-audit#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-governance-audit"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","governance","audit","normalize","hooks"],"pm":{"aliases":["governance-audit","audit"],"extensions":["extensions/governance-audit"],"catalog":{"display_name":"Governance Audit","category":"governance","summary":"Run dedupe audits, comments audits, and normalize sweeps as package-owned workflows.","tags":["governance","audit","normalize","hooks"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-governance-audit#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-governance-audit","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-guide-shell","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-guide-shell","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package for guide and shell completion workflows.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-guide-shell#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-guide-shell"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","guide","completion","shell"],"pm":{"aliases":["guide-shell"],"extensions":["extensions/guide-shell"],"catalog":{"display_name":"Guide + Shell UX","category":"workflow","summary":"Restore guide documentation and shell completion commands as package-owned UX surfaces.","tags":["guide","completion","shell"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-guide-shell#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-guide-shell","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-kanban","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-kanban","version":"2026.11.3","private":true,"type":"module","description":"First-party pm archetype package: a complete Kanban continuous-flow profile built on public SDK primitives.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-kanban#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-kanban"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","sdk","profile","archetype","kanban","exemplar"],"pm":{"aliases":["kanban"],"extensions":["extensions/kanban"],"catalog":{"display_name":"Kanban Archetype","category":"sdk","summary":"Installable Kanban continuous-flow archetype: Card item type, flow fields, and a ProjectProfileDefinition built on public SDK primitives.","tags":["sdk","profile","archetype","kanban","schema","exemplar"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-kanban#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-kanban","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-lifecycle-hooks","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-lifecycle-hooks","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package demonstrating safe lifecycle hook registration.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-lifecycle-hooks#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-lifecycle-hooks"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","hooks","lifecycle","sdk"],"pm":{"aliases":["lifecycle-hooks"],"extensions":["extensions/lifecycle-hooks"],"catalog":{"display_name":"Lifecycle Hooks","category":"sdk","summary":"Default-inert lifecycle hook exemplar for package authors.","tags":["hooks","lifecycle","sdk"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-lifecycle-hooks#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-lifecycle-hooks","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-linked-test-adapters","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-linked-test-adapters","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package for optional linked-test run management adapters and reporters.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-linked-test-adapters#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-linked-test-adapters"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","linked-tests","background-runs","test-runs"],"pm":{"aliases":["linked-test-adapters"],"extensions":["extensions/linked-test-adapters"],"catalog":{"display_name":"Linked Test Adapters","category":"testing","summary":"Restore optional linked-test run management/reporting command surfaces.","tags":["tests","linked-tests","background","reporting"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-linked-test-adapters#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-linked-test-adapters","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-search-advanced","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-search-advanced","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package for semantic, hybrid, and reindex search workflows.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-search-advanced#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-search-advanced"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","search","reindex","semantic","hybrid"],"pm":{"aliases":["search-advanced"],"extensions":["extensions/search-advanced"],"catalog":{"display_name":"Advanced Search","category":"search","summary":"Enable semantic/hybrid search modes and reindex workflows.","tags":["search","semantic","hybrid","reindex"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-search-advanced#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-search-advanced","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-templates","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-templates","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package for reusable create templates.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-templates#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-templates"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","templates"],"pm":{"aliases":["templates"],"extensions":["extensions/templates"],"catalog":{"display_name":"Create Templates","category":"workflow","summary":"Save, list, show, and apply reusable pm create option templates.","tags":["templates","create","workflow"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-templates#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-templates","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-todos","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-todos","version":"2026.11.3","private":true,"type":"module","description":"First-party pm package for Todo markdown import and export.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-todos#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-todos"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","project-management","todos"],"pm":{"aliases":["todos"],"extensions":["extensions/todos"],"catalog":{"display_name":"Todos Import/Export","category":"migration","summary":"Import and export Todo markdown tasks through pm package commands.","tags":["migration","todos","import","export"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-todos#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-todos","report":"https://github.com/unbraind/pm-cli/issues"}},"docs":["README.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@unbrained/pm-vcs-sdk-exemplar","version":"2026.11.
|
|
1
|
+
{"name":"@unbrained/pm-vcs-sdk-exemplar","version":"2026.11.3","private":true,"type":"module","description":"Beyond-PM exemplar: a VCS-style changeset workflow built entirely on public pm SDK and extension primitives.","homepage":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-vcs#readme","repository":{"type":"git","url":"git+https://github.com/unbraind/pm-cli.git","directory":"packages/pm-vcs"},"bugs":{"url":"https://github.com/unbraind/pm-cli/issues"},"keywords":["pm-package","sdk","vcs","event-sourcing","exemplar"],"pm":{"aliases":["vcs-exemplar"],"extensions":["extensions/vcs"],"catalog":{"display_name":"VCS SDK Exemplar","category":"sdk","summary":"Non-PM changeset/ref workflow proving custom schema, domain commands, hooks, history replay, and typed relationship events through public SDK contracts.","tags":["sdk","vcs","event-sourcing","graph","exemplar"],"links":{"docs":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-vcs#readme","repository":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-vcs","report":"https://github.com/unbraind/pm-cli/tree/main/packages/pm-vcs/GAP_REPORT.md"}},"docs":["README.md","GAP_REPORT.md"],"examples":["README.md"]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$schema":"https://json.schemastore.org/claude-code-plugin-manifest.json","name":"pm-claude","displayName":"pm CLI","description":"Native pm CLI integration for Claude Code — 32 MCP tools, 14 skills with slash invocations, 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.","version":"2026.11.
|
|
1
|
+
{"$schema":"https://json.schemastore.org/claude-code-plugin-manifest.json","name":"pm-claude","displayName":"pm CLI","description":"Native pm CLI integration for Claude Code — 32 MCP tools, 14 skills with slash invocations, 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.","version":"2026.11.3","author":{"name":"unbrained","url":"https://github.com/unbraind/pm-cli"},"homepage":"https://github.com/unbraind/pm-cli","repository":"https://github.com/unbraind/pm-cli","license":"MIT","keywords":["pm-cli","project-management","mcp","tasks","agents","workflows","git-native","task-tracker","ai"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"pm-claude-runtime","private":true,"type":"module","version":"2026.11.
|
|
1
|
+
{"name":"pm-claude-runtime","private":true,"type":"module","version":"2026.11.3","dependencies":{"@unbrained/pm-cli":"2026.11.3"}}
|