@unbrained/pm-cli 2026.8.17 → 2026.8.18
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 +2 -2
- package/AGENTS.md +4 -3
- package/CHANGELOG.md +35 -3
- package/README.md +3 -3
- package/dist/cli/error-guidance.js +7 -4
- package/dist/cli/register-list-query.js +132 -51
- package/dist/cli-bundle/bundle-manifest.json +146 -146
- package/dist/cli-bundle/chunks/chunk-5UZZAJKR.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-YM2YAMF7.js → chunk-ALDJGKAK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HBJAS566.js → chunk-BSK2IN3C.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-DY4DMUMC.js +197 -0
- package/dist/cli-bundle/chunks/{chunk-JOKATURE.js → chunk-GNFAFIJI.js} +9 -9
- package/dist/cli-bundle/chunks/chunk-L5Q2CLPE.js +35 -0
- package/dist/cli-bundle/chunks/{chunk-TPXZIBIV.js → chunk-PVRUN5ZS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7IBRGCHX.js → chunk-RZQTVMRQ.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-SARFF5H5.js +3 -0
- package/dist/cli-bundle/chunks/chunk-UYCLQVL2.js +13 -0
- package/dist/cli-bundle/chunks/{chunk-3UEGXBMR.js → chunk-YRGOLZA7.js} +58 -54
- package/dist/cli-bundle/chunks/register-list-query-I23LALEE.js +11 -0
- package/dist/cli-bundle/chunks/{register-mutation-4WBRPXLV.js → register-mutation-6YGU3GPH.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-SSENDH5B.js → register-operations-4HTFC6J7.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-DOSFBGKE.js → register-setup-PPPEF3SN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-2PN4TJXH.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZQPGZZWQ.js → chunk-3TKWMNKF.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-5AF3ZBNB.js +155 -0
- package/dist/cli-bundle/focused-chunks/chunk-C5IW2NDA.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-SYZENPIT.js → chunk-EUEGXZ2A.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-XKAMP5OU.js → chunk-EX6MKP2X.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-CYFK5UPB.js → chunk-K43KKAFS.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-ATEY76SX.js → chunk-M62NO7EI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-SALH6B6K.js → chunk-ODOVCP45.js} +5 -5
- package/dist/cli-bundle/focused-chunks/chunk-RNDNMARJ.js +16 -0
- package/dist/cli-bundle/focused-chunks/chunk-TN4AE665.js +26 -0
- package/dist/cli-bundle/focused-chunks/chunk-TVV2DONO.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-UI6AJ5TD.js +4 -0
- package/dist/cli-bundle/focused-chunks/{chunk-MHPIL773.js → chunk-V5XTGLK7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-KP2VQQVQ.js → chunk-WGHQVU6P.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-XYNBXTDQ.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-Z56ECT7I.js +2 -0
- package/dist/cli-bundle/main.js +7 -7
- 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 +31 -31
- 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 +32 -32
- 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 +4 -4
- package/dist/core/config/nested-settings.js +8 -2
- package/dist/core/extensions/exporter-output-contract.d.ts +12 -0
- package/dist/core/extensions/exporter-output-contract.js +67 -0
- package/dist/core/extensions/extension-types.d.ts +36 -1
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/loader.js +35 -44
- package/dist/core/history/event-index.d.ts +5 -0
- package/dist/core/history/event-index.js +133 -27
- package/dist/core/sentry/helpers.js +3 -3
- package/dist/core/shared/constants.js +5 -2
- package/dist/core/store/settings-validator.d.ts +4 -0
- package/dist/core/store/settings-validator.js +3 -2
- package/dist/core/store/settings.js +8 -2
- package/dist/mcp/tool-definitions.js +12 -7
- package/dist/sdk/agent/refusal-reachability.js +4 -4
- package/dist/sdk/authoring.d.ts +1 -1
- package/dist/sdk/authoring.js +2 -2
- package/dist/sdk/cli-bootstrap.d.ts +2 -2
- package/dist/sdk/cli-bootstrap.js +4 -4
- package/dist/sdk/cli-contracts/command-aliases.d.ts +34 -2
- package/dist/sdk/cli-contracts/command-aliases.js +64 -13
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
- package/dist/sdk/cli-contracts/flag-contracts.js +11 -7
- package/dist/sdk/cli-contracts/grammar-contracts.d.ts +70 -0
- package/dist/sdk/cli-contracts/grammar-contracts.js +345 -0
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +19 -2
- package/dist/sdk/cli-contracts/runtime-contracts.js +61 -14
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +7 -2
- package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
- package/dist/sdk/cli-contracts/tool-schema.js +20 -11
- package/dist/sdk/cli-contracts.d.ts +2 -2
- package/dist/sdk/cli-contracts.js +4 -4
- package/dist/sdk/completion.js +13 -15
- package/dist/sdk/compose.d.ts +3 -3
- package/dist/sdk/compose.js +2 -2
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +3 -2
- package/dist/sdk/core.d.ts +1 -1
- package/dist/sdk/core.js +3 -3
- package/dist/sdk/environment/host-environment-errors.js +3 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +54 -14
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -14
- package/dist/sdk/guide-topics.js +5 -5
- package/dist/sdk/index.d.ts +4 -3
- package/dist/sdk/index.js +6 -5
- package/dist/sdk/init-agent-guidance.js +3 -3
- package/dist/sdk/mutation-events.d.ts +18 -2
- package/dist/sdk/mutation-events.js +59 -16
- package/dist/sdk/output.d.ts +44 -0
- package/dist/sdk/output.js +28 -2
- package/dist/sdk/query/complete-list.d.ts +94 -0
- package/dist/sdk/query/complete-list.js +173 -0
- package/dist/sdk/query/list.js +5 -2
- package/dist/sdk/query.d.ts +1 -0
- package/dist/sdk/query.js +3 -2
- package/dist/sdk/read-output-contracts.d.ts +2 -2
- package/dist/sdk/read-output-contracts.js +36 -9
- package/dist/sdk/runtime-extended-actions.js +10 -2
- package/dist/sdk/runtime.d.ts +8 -2
- package/dist/sdk/runtime.js +11 -8
- package/dist/types.d.ts +5 -0
- package/dist/types.js +2 -2
- package/docs/AGENT_GUIDE.md +25 -9
- package/docs/CLI_GRAMMAR.md +106 -0
- package/docs/COMMANDS.md +23 -23
- package/docs/ONBOARDING.md +4 -4
- package/docs/QUICKSTART.md +1 -1
- package/docs/README.md +2 -0
- package/docs/RELEASING.md +30 -6
- package/docs/SDK.md +36 -2
- package/docs/SDK_ARTIFACT_OUTPUT.md +72 -0
- package/docs/SDK_CONTEXT_COORDINATION.md +46 -12
- package/docs/agent-task-token-baseline.json +5 -5
- package/marketplace.json +2 -2
- package/package.json +3 -2
- 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-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +652 -31
- package/dist/cli-bundle/chunks/chunk-2QLOXC3V.js +0 -3
- package/dist/cli-bundle/chunks/chunk-4JPYF536.js +0 -35
- package/dist/cli-bundle/chunks/chunk-6VDLG2FC.js +0 -13
- package/dist/cli-bundle/chunks/chunk-ION3E43Q.js +0 -197
- package/dist/cli-bundle/chunks/chunk-OAC5NIV4.js +0 -3
- package/dist/cli-bundle/chunks/register-list-query-Q7KII4G5.js +0 -10
- package/dist/cli-bundle/focused-chunks/chunk-267MUUS6.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-2NNFLLNG.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2QSAKMIH.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-BUCG4ZI2.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-EHXIKD6K.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-KGEXTMPG.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-POEEAD2V.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-XPIC53VA.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-ZT2DJS27.js +0 -155
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Noun–Verb CLI Grammar and Compatibility Policy
|
|
2
|
+
|
|
3
|
+
Tracked by [pm-pbyu](../.agents/pm/decisions/pm-pbyu.toon), implemented through [pm-0z7n](../.agents/pm/features/pm-0z7n.toon), [pm-pfqi](../.agents/pm/tasks/pm-pfqi.toon), [pm-yy8rmx](../.agents/pm/tasks/pm-yy8rmx.toon), and [pm-wt43zj](../.agents/pm/tasks/pm-wt43zj.toon).
|
|
4
|
+
|
|
5
|
+
## Agent Quick Context
|
|
6
|
+
|
|
7
|
+
Use the canonical noun-first form when generating commands. Existing spellings remain executable, but deprecated compatibility aliases are absent from default help and completion discovery and emit one migration hint on stderr. Machine clients can read alias lifecycle and replacement tokens from `pm contracts --full --json`.
|
|
8
|
+
|
|
9
|
+
The first completed consolidation is the list family:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pm list # active lifecycle rows
|
|
13
|
+
pm list --status open # one lifecycle class
|
|
14
|
+
pm list --status open,blocked # several classes
|
|
15
|
+
pm list --status blocked # status- or dependency-blocked semantics
|
|
16
|
+
pm list --all # every lifecycle status
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`list-all`, `list-draft`, `list-open`, `list-in-progress`, `list-blocked`, `list-closed`, and `list-canceled` preserve command results and stdout behavior. Their documented migration hint may add one stderr line.
|
|
20
|
+
|
|
21
|
+
## Status
|
|
22
|
+
|
|
23
|
+
Accepted. The grammar contract, destination census, and compatibility policy are executable SDK data and mandatory static gates.
|
|
24
|
+
|
|
25
|
+
## Context
|
|
26
|
+
|
|
27
|
+
pm grew by adding one top-level spelling per feature. That made help, completions, contracts, documentation, and agent routing grow linearly even when several commands represented the same concept. The list family alone repeated almost the same help surface eight times. A universal project-management tool needs extensible behavior without requiring every agent to memorize an ever-growing flat vocabulary.
|
|
28
|
+
|
|
29
|
+
The governing product principle is `project management = context management`: command discovery must route an agent to the smallest authoritative context, while compatibility must preserve scripts and historical instructions.
|
|
30
|
+
|
|
31
|
+
## Decision Drivers
|
|
32
|
+
|
|
33
|
+
- Preserve every published invocation and its stdout behavior.
|
|
34
|
+
- Keep frequent operations concise without making aliases the discovery model.
|
|
35
|
+
- Make domain ownership explicit enough to generate routing, help, completions, SDK contracts, MCP projections, and documentation.
|
|
36
|
+
- Prevent surface regrowth with a fail-closed, bidirectional contract gate.
|
|
37
|
+
- Let packages add domain behavior without consuming the core noun budget.
|
|
38
|
+
- Make migration guidance suppressible for automation while keeping canonical replacements machine-readable.
|
|
39
|
+
|
|
40
|
+
## Alternatives Considered
|
|
41
|
+
|
|
42
|
+
### Flat surface status quo
|
|
43
|
+
|
|
44
|
+
Rejected. Each feature adds another root spelling and duplicates contract/help context. A byte-count snapshot records growth but does not decide whether the new command belongs in the architecture.
|
|
45
|
+
|
|
46
|
+
### Pure git-style subcommands
|
|
47
|
+
|
|
48
|
+
Rejected as an exclusive rule. Noun-first paths are canonical, but forcing high-frequency operations such as `create`, `get`, `update`, `claim`, and `close` to pay an extra token on every invocation would regress the agent hot path. Named permanent aliases may remain visible and are distinguished from deprecated compatibility shims in contract data.
|
|
49
|
+
|
|
50
|
+
### BusyBox-style multi-binary surface
|
|
51
|
+
|
|
52
|
+
Rejected. Separate binaries multiply distribution, signing, package resolution, documentation, and shell-discovery surfaces without improving domain routing.
|
|
53
|
+
|
|
54
|
+
## Decision
|
|
55
|
+
|
|
56
|
+
1. The core routing vocabulary has twelve nouns: `item`, `list`, `context`, `search`, `graph`, `history`, `workspace`, `package`, `ops`, `plan`, `contracts`, and `help`.
|
|
57
|
+
2. Canonical forms are noun-first. Verbs and facets are subcommands; projections and predicates are flags.
|
|
58
|
+
3. Shared semantics use a shared verb vocabulary. Noun-specific verbs require an explicit checked-in disposition.
|
|
59
|
+
4. Scope precedes its operation: for example, `workspace snapshot create`, not `workspace create snapshot`.
|
|
60
|
+
5. Package-owned commands are declared as such and do not silently expand the core noun set.
|
|
61
|
+
6. Published spellings are not removed. Deprecated spellings are hidden aliases with a canonical token sequence, PM owner, lifecycle, and one stderr migration hint.
|
|
62
|
+
7. Permanent hot-path aliases and deprecated aliases are different contract states. Permanent aliases are ergonomic API; deprecated aliases are compatibility state.
|
|
63
|
+
8. Every live command has exactly one destination row. A row may name its target noun, a tracked consolidation owner, a package owner, or a reasoned keep-as-is exception.
|
|
64
|
+
9. The census is bidirectional: missing live rows and stale checked-in rows both fail CI.
|
|
65
|
+
10. Default-visible top-level growth is ceilinged. Lowering the ceiling is always valid; raising it requires a tracked noun-placement decision rather than regenerating a baseline.
|
|
66
|
+
|
|
67
|
+
## SDK Contract
|
|
68
|
+
|
|
69
|
+
Package authors and embedded clients use the public exports:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import {
|
|
73
|
+
PM_CLI_GRAMMAR_CONTRACT,
|
|
74
|
+
PM_COMMAND_ALIAS_CONTRACTS,
|
|
75
|
+
PM_COMMAND_DESTINATION_CONTRACTS,
|
|
76
|
+
resolvePmCommandAlias,
|
|
77
|
+
verifyPmCliGrammar,
|
|
78
|
+
} from "@unbrained/pm-cli/sdk";
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`PM_COMMAND_ALIAS_CONTRACTS` carries `alias`, `canonical`, `canonical_argv`, `lifecycle`, `hidden`, `registration`, and `owner`. `verifyPmCliGrammar` returns deterministic findings with an offending spelling and nearest conforming target.
|
|
82
|
+
|
|
83
|
+
Runtime contracts expose the compact noun/verb policy in summary output and include the exhaustive destination census in full output. Deprecated aliases remain queryable but are excluded from the default command-summary denominator.
|
|
84
|
+
|
|
85
|
+
## Compatibility and Migration Hints
|
|
86
|
+
|
|
87
|
+
Hints go to stderr exactly once per deprecated-alias invocation and never alter stdout. Disable them for a project when an automation intentionally retains old spellings:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pm config project set ux_deprecation_hints false
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This setting changes presentation only. It does not disable aliases or change command results. The uniform machine result-envelope receipt is intentionally deferred to its separately tracked cross-command contract so this implementation does not create a list-only shape.
|
|
94
|
+
|
|
95
|
+
## Enforcement
|
|
96
|
+
|
|
97
|
+
`pnpm quality:command-grammar` builds the SDK, reads the live runtime command contracts, and compares them with the checked-in destination and alias tables. Package-owned destination rows are conditional because installed packages vary by workspace; every activated package command still requires a declared row, while an inactive package does not make its row stale. The gate also proves parity between discoverable SDK actions, the MCP `pm_run` action enum, and narrow MCP tools. The same gate runs inside `quality:static`, alongside contract drift checks. Its negative controls prove that unknown commands, stale core rows, broken alias targets, MCP drift, and surface-ceiling growth fail upward.
|
|
98
|
+
|
|
99
|
+
## Consequences
|
|
100
|
+
|
|
101
|
+
- Agents discover one list command instead of eight repeated help pages.
|
|
102
|
+
- Existing scripts keep working and receive an actionable replacement.
|
|
103
|
+
- CLI, SDK, completion, and contract consumers share one alias table.
|
|
104
|
+
- New commands require an explicit architectural home and PM owner.
|
|
105
|
+
- The compatibility table is long-lived public API and must be reviewed like any other SDK contract.
|
|
106
|
+
- Consolidation proceeds incrementally: current legacy commands may remain only with a named disposition until their owning PM item lands.
|
package/docs/COMMANDS.md
CHANGED
|
@@ -141,8 +141,8 @@ pm search "calendar reminder validation" --limit 10
|
|
|
141
141
|
pm get pm-a1b2 # read one item; add --fields/--depth for lower-token projections
|
|
142
142
|
pm get pm-a1b2 --tree --tree-depth 2 # item plus its descendant subtree
|
|
143
143
|
pm get pm-a1b2 --at 7 # verified, mutation-free historical version
|
|
144
|
-
pm list
|
|
145
|
-
pm list
|
|
144
|
+
pm list --status open --type Task --priority 1 --limit 20
|
|
145
|
+
pm list --status in_progress --limit 20
|
|
146
146
|
pm aggregate --group-by parent,type --status open
|
|
147
147
|
pm aggregate --group-by parent,type --completion --include-unparented
|
|
148
148
|
pm duplicates --status all --threshold 0.8
|
|
@@ -173,7 +173,7 @@ Each aggregate row carries an explicit `group_label`: a blank/null group value (
|
|
|
173
173
|
`--sort` accepts `priority|deadline|updated_at|created_at|title|parent`, plus the convenience aliases `updated` (→ `updated_at`) and `created` (→ `created_at`):
|
|
174
174
|
|
|
175
175
|
```bash
|
|
176
|
-
pm list
|
|
176
|
+
pm list --all --sort updated --order desc
|
|
177
177
|
```
|
|
178
178
|
|
|
179
179
|
### Incremental "what changed since" filters
|
|
@@ -182,16 +182,16 @@ Every `list*` command accepts `--updated-after`/`--updated-before`/`--created-af
|
|
|
182
182
|
|
|
183
183
|
```bash
|
|
184
184
|
# Items touched since my last context window (feed back the previous run's `now`)
|
|
185
|
-
pm list
|
|
185
|
+
pm list --all --updated-after 2026-06-04T15:18:32Z --brief
|
|
186
186
|
|
|
187
187
|
# Relative offsets are SIGNED: -2h/-7d reach into the past, +1d into the future.
|
|
188
188
|
# Units are h/d/w/m (m = months — there is no minutes unit).
|
|
189
|
-
pm list
|
|
190
|
-
pm list
|
|
189
|
+
pm list --status open --updated-after=-2h --brief
|
|
190
|
+
pm list --status open --created-after=-7d
|
|
191
191
|
|
|
192
|
-
# Common list windows avoid date math (`list
|
|
193
|
-
pm list
|
|
194
|
-
pm list
|
|
192
|
+
# Common list windows avoid date math (`pm list --status open` keeps the view open-only).
|
|
193
|
+
pm list --status open --today --brief
|
|
194
|
+
pm list --all --recent --brief
|
|
195
195
|
|
|
196
196
|
# Search scoped to open work only (drops closed-history noise); statuses accept
|
|
197
197
|
# all (no lifecycle restriction), open/closed/canceled aliases, or configured
|
|
@@ -293,12 +293,12 @@ pm eval --fail-under 0.6 --json # CI gate: exit non-zero when aggregate nDC
|
|
|
293
293
|
|
|
294
294
|
### Full results, totals, and bodies
|
|
295
295
|
|
|
296
|
-
`pm list
|
|
296
|
+
`pm list` returns every matched row when neither `--limit` nor `--offset` is set. Every JSON/TOON result has the same pagination envelope: `total` is the pre-pagination match count, `has_more` and `truncated` are booleans, and `next_cursor` is either the continuation token or `null`. `completeness` reports whether the corpus was `complete`, `partial`, or `unchecked` (derived-index page), with unreadable item/directory counts. Use `--strict-read` when omissions must fail the command. The `filters` object omits unset values instead of emitting null placeholders, keeping long-running agent context stable and lean. Pass `--no-truncate` to force the entire matched set and override any `--limit` in one call. `--all` selects every lifecycle status; combine the flags for an unbounded all-status audit:
|
|
297
297
|
|
|
298
298
|
```bash
|
|
299
|
-
pm list
|
|
300
|
-
pm list
|
|
301
|
-
pm list
|
|
299
|
+
pm list --all --no-truncate --brief # every matched row, ignoring any --limit
|
|
300
|
+
pm list --status open --limit 20 --json # stable total/has_more/truncated/next_cursor envelope
|
|
301
|
+
pm list --all --strict-read --json # fail if any source item cannot be read
|
|
302
302
|
```
|
|
303
303
|
|
|
304
304
|
Compatibility note: older responses emitted `total` only when pagination
|
|
@@ -312,7 +312,7 @@ unconditional pre-pagination match count, branch on `has_more` or
|
|
|
312
312
|
JSON output is compact by default (id/status/type/title) for token efficiency. To pull item bodies in bulk in a single call — instead of one `pm get` per item — add `--include-body`, which expands each row to the full field set plus `body`:
|
|
313
313
|
|
|
314
314
|
```bash
|
|
315
|
-
pm list
|
|
315
|
+
pm list --status open --json --include-body # full fields + body for every returned row
|
|
316
316
|
```
|
|
317
317
|
|
|
318
318
|
`pm get <id> --json` returns the item's `body` **inside** the `item` object (i.e. `.item.body`), matching where `list --include-body` places it and the long-form `description`/`acceptance_criteria` fields — so a single read exposes every field at a consistent path. Body is included at the default `standard` depth and above; `--depth brief` omits it.
|
|
@@ -322,10 +322,10 @@ pm list-open --json --include-body # full fields + body for every return
|
|
|
322
322
|
`pm list*` accepts `--format <csv|table|json|ndjson|toon>` to choose how rows render. `csv` and `table` are **human export** modes — pipe them into a spreadsheet or read them directly in a terminal — while `json`/`toon` override the machine output format the same way the global `--json` flag does. `ndjson` writes each projected item as one self-contained JSON object per line, with no wrapper or trailing summary. The rendered fields follow the active projection, so combine `--format` with `--fields`/`--brief`/`--compact` to control exactly what appears:
|
|
323
323
|
|
|
324
324
|
```bash
|
|
325
|
-
pm list
|
|
326
|
-
pm list
|
|
327
|
-
pm list
|
|
328
|
-
pm list
|
|
325
|
+
pm list --status open --format table # aligned, monospace-friendly columns
|
|
326
|
+
pm list --all --fields id,title,priority --format csv # spreadsheet export with chosen columns
|
|
327
|
+
pm list --status open --format csv > backlog.csv # capture for reporting
|
|
328
|
+
pm list --all --brief --format ndjson | jq -c 'select(.status == "open")'
|
|
329
329
|
```
|
|
330
330
|
|
|
331
331
|
CSV output is RFC 4180 compliant (values with commas, quotes, or newlines are quoted; array fields such as `tags` join with `;`). `--format csv|table|ndjson` cannot be combined with the legacy envelope-oriented `--stream` mode.
|
|
@@ -338,13 +338,13 @@ The same `list*` commands and `pm search` extend this with governance-field pres
|
|
|
338
338
|
|
|
339
339
|
```bash
|
|
340
340
|
# Find open Tasks that still need acceptance criteria
|
|
341
|
-
pm list
|
|
341
|
+
pm list --status open --type Task --filter-ac-missing --brief
|
|
342
342
|
|
|
343
343
|
# Closed items that were never given a resolution
|
|
344
|
-
pm list
|
|
344
|
+
pm list --status closed --filter-resolution-missing --json
|
|
345
345
|
|
|
346
346
|
# Open items that still need a reviewer assigned
|
|
347
|
-
pm list
|
|
347
|
+
pm list --status open --filter-reviewer-missing --brief
|
|
348
348
|
```
|
|
349
349
|
|
|
350
350
|
### Content-field presence filters
|
|
@@ -353,10 +353,10 @@ pm list-open --filter-reviewer-missing --brief
|
|
|
353
353
|
|
|
354
354
|
```bash
|
|
355
355
|
# Closed items that shipped no documented learnings
|
|
356
|
-
pm list
|
|
356
|
+
pm list --status closed --no-learnings --brief
|
|
357
357
|
|
|
358
358
|
# Open work that has linked tests but no linked files yet
|
|
359
|
-
pm list
|
|
359
|
+
pm list --status open --has-tests --no-files --json
|
|
360
360
|
```
|
|
361
361
|
|
|
362
362
|
## Bulk Operations
|
package/docs/ONBOARDING.md
CHANGED
|
@@ -41,8 +41,8 @@ Use progressive disclosure:
|
|
|
41
41
|
```bash
|
|
42
42
|
pm context --limit 10
|
|
43
43
|
pm search "<request keywords>" --limit 10
|
|
44
|
-
pm list
|
|
45
|
-
pm list
|
|
44
|
+
pm list --status open --limit 20
|
|
45
|
+
pm list --status in_progress --limit 20
|
|
46
46
|
pm install guide-shell --project
|
|
47
47
|
pm guide workflows
|
|
48
48
|
```
|
|
@@ -82,8 +82,8 @@ The canonical loop is maintained in [AGENT_GUIDE.md](AGENT_GUIDE.md) — this is
|
|
|
82
82
|
```bash
|
|
83
83
|
pm context --limit 10
|
|
84
84
|
pm search "<keywords>" --limit 10
|
|
85
|
-
pm list
|
|
86
|
-
pm list
|
|
85
|
+
pm list --status open --limit 20
|
|
86
|
+
pm list --status in_progress --limit 20
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
2. Claim and start
|
package/docs/QUICKSTART.md
CHANGED
|
@@ -94,7 +94,7 @@ Useful item types:
|
|
|
94
94
|
```bash
|
|
95
95
|
pm context --limit 10
|
|
96
96
|
pm search "restore lock retry" --limit 10
|
|
97
|
-
pm list
|
|
97
|
+
pm list --status open --limit 20
|
|
98
98
|
pm claim <item-id>
|
|
99
99
|
pm update <item-id> --status in_progress --message "Start implementation"
|
|
100
100
|
pm update <item-id> --add-tags urgent,backend
|
package/docs/README.md
CHANGED
|
@@ -40,9 +40,11 @@ pm guide release --json
|
|
|
40
40
|
- [Testing](TESTING.md) - sandbox-safe local tests and linked-test orchestration.
|
|
41
41
|
- [Security Governance](SECURITY_GOVERNANCE.md) - vulnerability reporting, review discipline, property fuzzing, and OpenSSF limitations.
|
|
42
42
|
- [Architecture](ARCHITECTURE.md) - contributor internals: storage, mutation flow, search, extensions, and command contracts.
|
|
43
|
+
- [Noun–Verb CLI Grammar](CLI_GRAMMAR.md) - accepted command architecture, exhaustive destination census, hidden aliases, and the surface-growth gate.
|
|
43
44
|
- [SDK Primitive Inventory](SDK_PRIMITIVE_INVENTORY.md) - SDK-first migration map and private-import ratchet for CLI/MCP layering.
|
|
44
45
|
- [Package SDK Contract Conformance](PACKAGE_SDK_CONTRACT_CONFORMANCE.md) - authoritative public types, `typeof` module derivation, and the first-party parity gate.
|
|
45
46
|
- [SDK Action and Boundary Conformance](SDK_ACTION_CONFORMANCE.md) - derived CLI/SDK/MCP action vocabulary, public-import ratchets, intent budget diagnostics, and package-runner proof.
|
|
47
|
+
- [SDK Artifact Output Contracts](SDK_ARTIFACT_OUTPUT.md) - clean stdout/file exporter channels, bounded receipts, binary-safe delivery, and shared NDJSON terminal framing.
|
|
46
48
|
- [Context Relevance and Packing](CONTEXT_RELEVANCE.md) - shared CLI/SDK signals, derived-store provenance, ranking explanations, and token budgets.
|
|
47
49
|
- [Output Projection and Omission Contracts](OUTPUT_PROJECTION_CONTRACTS.md) - explicit withheld-field receipts, mode-paired row keys, and completion resolver outcomes.
|
|
48
50
|
- [Output Token Accounting](OUTPUT_TOKEN_ACCOUNTING.md) - opt-in CLI/MCP byte attribution, bounded receipt overhead, and release-level tokens-per-task baselines.
|
package/docs/RELEASING.md
CHANGED
|
@@ -27,7 +27,8 @@ The local/hosted gate selection contract is tracked by
|
|
|
27
27
|
[pm-ei6x66](../.agents/pm/tasks/pm-ei6x66.toon). Release-candidate analyzer
|
|
28
28
|
provenance is tracked by [pm-u1baah](../.agents/pm/issues/pm-u1baah.toon), and
|
|
29
29
|
authoritative blocker-recovery run selection by
|
|
30
|
-
[pm-db8onn](../.agents/pm/issues/pm-db8onn.toon)
|
|
30
|
+
[pm-db8onn](../.agents/pm/issues/pm-db8onn.toon), and queued automatic
|
|
31
|
+
same-day recovery by [pm-dm2vfz](../.agents/pm/issues/pm-dm2vfz.toon).
|
|
31
32
|
|
|
32
33
|
## Version Policy
|
|
33
34
|
|
|
@@ -78,11 +79,11 @@ Policy:
|
|
|
78
79
|
created, a non-`github-actions[bot]` closure of the exact bot-created
|
|
79
80
|
`Auto Release blocked` issue on the same UTC day triggers one preparation
|
|
80
81
|
retry
|
|
81
|
-
- if today's tag already exists, blocker closure bypasses
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
- if today's tag already exists, a queued schedule or blocker closure bypasses
|
|
83
|
+
candidate preparation and accepts the immutable result only after independent
|
|
84
|
+
public-distribution evidence confirms the exact release; incomplete
|
|
85
|
+
publication continues through bounded recovery instead of being accepted
|
|
86
|
+
from tag presence alone
|
|
86
87
|
- release preparation must pass all quality and compatibility gates before commit+tag push
|
|
87
88
|
- before dependency installation or build, auto-release verifies that the
|
|
88
89
|
candidate has exact-commit analyzer results or an immutable tree-identical
|
|
@@ -104,6 +105,10 @@ Policy:
|
|
|
104
105
|
before release mutation and reported as `retry_already_attempted`, and
|
|
105
106
|
workflow cleanup closures by `github-actions[bot]` are ignored.
|
|
106
107
|
- after a scheduled run publishes a tag and the downstream release workflow succeeds, auto-release closes any open `Auto Release blocked` issue so the GitHub tracker reflects current release health
|
|
108
|
+
- workflow concurrency can leave a delayed schedule queued behind another
|
|
109
|
+
production run. The queued schedule resolves the current UTC-day immutable
|
|
110
|
+
result before candidate provenance, proves publication, and exits without
|
|
111
|
+
evaluating the generated release commit as a new candidate
|
|
107
112
|
|
|
108
113
|
Pipeline entrypoint:
|
|
109
114
|
|
|
@@ -268,6 +273,25 @@ confirms that exact merge SHA, `main` base, and reviewed head. Remediate a
|
|
|
268
273
|
refused direct-main candidate by landing the next tree-changing fix through a
|
|
269
274
|
reviewed PR; never copy, synthesize, or bypass analyzer evidence.
|
|
270
275
|
|
|
276
|
+
### Reviewed Delivery Closeout
|
|
277
|
+
|
|
278
|
+
The reviewed delivery includes its PM evidence, item closure, and generated
|
|
279
|
+
changelog. Complete those mutations on the implementation branch before merge
|
|
280
|
+
whenever their evidence is already available. A pull request is not complete
|
|
281
|
+
while known tracker or changelog closeout remains queued for a direct push.
|
|
282
|
+
|
|
283
|
+
When a repository update genuinely depends on the merge SHA or a post-merge
|
|
284
|
+
hosted result, create a normal follow-up branch from `main` and land that update
|
|
285
|
+
through another reviewed pull request. Do not push `.agents/pm/**` or
|
|
286
|
+
`CHANGELOG.md` closeout directly to `main`. Although tracker-only commits do not
|
|
287
|
+
create package-release eligibility by themselves, the direct commit still
|
|
288
|
+
becomes the default-branch head and lacks the reviewed analyzer evidence needed
|
|
289
|
+
by the next release-relevant candidate. `Release analyzer readiness (main)`
|
|
290
|
+
must fail closed in that state; its failure is a provenance control, not an
|
|
291
|
+
analyzer approval. Restore readiness only with a tree-changing, `main`-based,
|
|
292
|
+
reviewed pull request—never by copying statuses, weakening the gate, or
|
|
293
|
+
synthesizing a pull-request association.
|
|
294
|
+
|
|
271
295
|
```bash
|
|
272
296
|
# Read-only parity check
|
|
273
297
|
pnpm release:pipeline:dry-run
|
package/docs/SDK.md
CHANGED
|
@@ -47,6 +47,9 @@ first-class recurrence relationships are tracked by
|
|
|
47
47
|
[pm-rf120g](../.agents/pm/tasks/pm-rf120g.toon),
|
|
48
48
|
[pm-3crymx](../.agents/pm/issues/pm-3crymx.toon), and
|
|
49
49
|
[pm-ouyq3n](../.agents/pm/issues/pm-ouyq3n.toon).
|
|
50
|
+
Fail-closed whole-corpus reads and package-catalog output controls are tracked by
|
|
51
|
+
[pm-y4aaol](../.agents/pm/issues/pm-y4aaol.toon) and
|
|
52
|
+
[pm-2firut](../.agents/pm/issues/pm-2firut.toon).
|
|
50
53
|
|
|
51
54
|
Use it for extension authoring, package authoring, command/action contract discovery, and deterministic app or CI automation. Do not import private `src/core/...` modules from external integrations or packages.
|
|
52
55
|
|
|
@@ -199,6 +202,7 @@ Source of truth:
|
|
|
199
202
|
- [`src/sdk/merge/index.ts`](../src/sdk/merge/index.ts)
|
|
200
203
|
- [`src/sdk/workspace-transaction-gc.ts`](../src/sdk/workspace-transaction-gc.ts)
|
|
201
204
|
- [`src/sdk/query/list.ts`](../src/sdk/query/list.ts)
|
|
205
|
+
- [`src/sdk/query/complete-list.ts`](../src/sdk/query/complete-list.ts)
|
|
202
206
|
- [`src/sdk/query/search.ts`](../src/sdk/query/search.ts)
|
|
203
207
|
- [`src/sdk/query/search-pagination.ts`](../src/sdk/query/search-pagination.ts)
|
|
204
208
|
- [`src/sdk/query/search-rendering.ts`](../src/sdk/query/search-rendering.ts)
|
|
@@ -292,7 +296,7 @@ Storage format-version exports (under `@unbrained/pm-cli/sdk/runtime`):
|
|
|
292
296
|
Command/action contract exports:
|
|
293
297
|
|
|
294
298
|
- `PmClient` / `runAction` (high-level in-process action execution for custom tools, bots, CI, and embedded runtimes)
|
|
295
|
-
- Typed read primitives on `PmClient`: `get` (including `GetOptions.at` point-in-time reads), `list`, `search`, `context`, `next`, `aggregate`, `stats`, and `duplicates`; direct `getItemAt` reconstructs a canonical historical document without mutation. `duplicates` performs one bounded all-status metadata sweep and returns deterministic canonical-candidate and close-command guidance without mutating items.
|
|
299
|
+
- Typed read primitives on `PmClient`: `get` (including `GetOptions.at` point-in-time reads), `list`, `listAllComplete`, `search`, `context`, `next`, `aggregate`, `stats`, and `duplicates`; direct `getItemAt` reconstructs a canonical historical document without mutation. `listAllComplete` forces an all-status, full, strict, unbounded read and fails closed unless the returned envelope proves source completeness, unique ids, exact counts, no pagination, no field or budget omission, and no session projection. `duplicates` performs one bounded all-status metadata sweep and returns deterministic canonical-candidate and close-command guidance without mutating items.
|
|
296
300
|
- Read primitive option/result contracts: `GetOptions` / `GetResult`, `ListOptions` / `ListResult`, `SearchOptions` / `SearchResult`, `ContextOptions` / `ContextResult`, `NextOptions` / `NextResult`, `AggregateOptions` / `AggregateResult`, `StatsCommandOptions` / `StatsResult`. Standard and brief `get` projections omit note bodies but expose `item.notes_count`; deep/full reads return the notes themselves, and narrow consumers can request `notes_count` explicitly.
|
|
297
301
|
- Stream projection primitive: `serializeNdjsonRows` frames SDK-owned object rows as newline-delimited JSON without a trailing newline and rejects scalar/array rows, so package transports can match list/search/context CLI semantics without importing presentation code.
|
|
298
302
|
- Context relevance primitives: `buildItemContextRelevanceCandidates`, `buildContextSignalSnapshot`, `ContextSignalStore`, `JsonFileContextSignalStoreAdapter`, `parseContextSignalSnapshot`, `defaultScoreContextCandidates`, `scoreContextCandidates`, `scoreContextCandidatesWithActiveExtensions`, `evaluateContextRanking`, `runContextEvaluationScenario`, `runContextEvaluationCorpus`, and `summarizeContextEvaluationReports`
|
|
@@ -1468,6 +1472,10 @@ helpers return `ExtensionCommandResult`; both names describe the same lifecycle
|
|
|
1468
1472
|
payload shape with vocabulary-appropriate SDK signatures. `UpgradeResult` is the
|
|
1469
1473
|
same structured payload rendered by the CLI, so embedded tools can own their
|
|
1470
1474
|
presentation layer while sharing pm's package/install/doctor semantics.
|
|
1475
|
+
`packageCatalog` is a read surface and accepts the universal output controls;
|
|
1476
|
+
the CLI-equivalent `pm --output-budget unbounded package --catalog --json`
|
|
1477
|
+
therefore composes with the same output contract while catalog-plus-mutation
|
|
1478
|
+
invocations fail before any package state can change.
|
|
1471
1479
|
|
|
1472
1480
|
Annotation and relationship convenience methods turn "project management =
|
|
1473
1481
|
context management" into a typed SDK surface. Use `pm.comments`, `pm.notes`,
|
|
@@ -1576,9 +1584,35 @@ compact or `fields` projections return `ListProjectedItem` dictionaries. Use
|
|
|
1576
1584
|
a `partial` scan with unreadable item/directory counts, and an `unchecked`
|
|
1577
1585
|
derived-index page. Set `ListOptions.strictRead` (CLI `--strict-read`) when an
|
|
1578
1586
|
automation must fail instead of accepting omissions.
|
|
1579
|
-
`full: true` when an integration requires complete item metadata; the overload
|
|
1587
|
+
Use `full: true` when an integration requires complete item metadata; the overload
|
|
1580
1588
|
then returns `ListFullResult` without an assertion or cast.
|
|
1581
1589
|
|
|
1590
|
+
When correctness depends on the entire workspace rather than a page, use the
|
|
1591
|
+
certifying primitive instead of rebuilding these conditions at every call site:
|
|
1592
|
+
|
|
1593
|
+
```ts
|
|
1594
|
+
import {
|
|
1595
|
+
PmClient,
|
|
1596
|
+
certifyCompleteListResult,
|
|
1597
|
+
createCompleteListOptions,
|
|
1598
|
+
} from "@unbrained/pm-cli/sdk/runtime";
|
|
1599
|
+
|
|
1600
|
+
const pm = new PmClient({ pmRoot: "/workspace/.agents/pm" });
|
|
1601
|
+
const corpus = await pm.listAllComplete({ includeBody: true });
|
|
1602
|
+
corpus.complete_list.source_complete; // true, otherwise the call throws
|
|
1603
|
+
|
|
1604
|
+
// Custom transports can apply the same request and certificate independently.
|
|
1605
|
+
const candidate = await pm.list(createCompleteListOptions());
|
|
1606
|
+
const certified = certifyCompleteListResult(candidate);
|
|
1607
|
+
```
|
|
1608
|
+
|
|
1609
|
+
`PmCompleteListValidationError.receipt` lists every failed invariant and carries
|
|
1610
|
+
the exact recovery command
|
|
1611
|
+
`pm list-all --full --strict-read --no-truncate --output-budget unbounded --json`.
|
|
1612
|
+
The helper never infers completeness from a large limit: derived-index reads,
|
|
1613
|
+
terminal-state filtering, duplicate ids, cursor/session projection, compaction,
|
|
1614
|
+
and any omission receipt all prevent certification.
|
|
1615
|
+
|
|
1582
1616
|
CLI JSON consumers can add `--lean` to compact null and empty values. On
|
|
1583
1617
|
item-list envelopes, lean output also removes request echoes (`filters`, `now`,
|
|
1584
1618
|
`projection`, and `sorting`) and removes `next_cursor` when `has_more` is not
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# SDK artifact output contracts
|
|
2
|
+
|
|
3
|
+
Trackers: [pm-dilou2](../.agents/pm/issues/pm-dilou2.toon) and [pm-mav1ak](../.agents/pm/features/pm-mav1ak.toon).
|
|
4
|
+
|
|
5
|
+
Exporter artifacts are data streams, not command receipts. A package declares
|
|
6
|
+
the channel when it registers an exporter so the host never guesses whether a
|
|
7
|
+
returned value should be appended to artifact bytes.
|
|
8
|
+
|
|
9
|
+
## Agent quick context
|
|
10
|
+
|
|
11
|
+
- Declare `output.channel: "stdout"` for JSON, NDJSON, CSV, or opaque bytes.
|
|
12
|
+
The host suppresses its receipt by default, including under global `--json`.
|
|
13
|
+
- Declare `output.channel: "file"` when the exporter writes a file. The host
|
|
14
|
+
renders the returned bounded receipt by default.
|
|
15
|
+
- An exporter may still return a structured result. Suppressed receipts remain
|
|
16
|
+
available to hooks, telemetry, and embedding hosts.
|
|
17
|
+
- Write optional human progress or summaries to stderr. Never mix them into a
|
|
18
|
+
stdout artifact.
|
|
19
|
+
- Legacy registrations without `output` retain their previous rendering.
|
|
20
|
+
|
|
21
|
+
## Registration
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import type { ExtensionApi } from "@unbrained/pm-cli/sdk";
|
|
25
|
+
|
|
26
|
+
export function activate(api: ExtensionApi): void {
|
|
27
|
+
api.registerExporter(
|
|
28
|
+
"report-json",
|
|
29
|
+
async () => {
|
|
30
|
+
process.stdout.write('{"items":[]}\n');
|
|
31
|
+
return { exported: 0 };
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
description: "Export a complete JSON report to stdout.",
|
|
35
|
+
output: {
|
|
36
|
+
channel: "stdout",
|
|
37
|
+
media_type: "application/json",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The normalized contract is visible in the extension contribution inventory.
|
|
45
|
+
Derived help also states that stdout artifact bytes are exclusive and host
|
|
46
|
+
receipt rendering is suppressed when the extension does not supply a custom
|
|
47
|
+
description.
|
|
48
|
+
|
|
49
|
+
## Channel behavior
|
|
50
|
+
|
|
51
|
+
| Artifact channel | Default receipt | stdout | stderr |
|
|
52
|
+
| --- | --- | --- | --- |
|
|
53
|
+
| `stdout` | `suppress` | Artifact bytes only | Extension-owned diagnostics or summary |
|
|
54
|
+
| `file` | `render` | Bounded structured receipt | Extension-owned diagnostics |
|
|
55
|
+
|
|
56
|
+
File exporters may select `receipt: "render"` or `receipt: "suppress"` as an
|
|
57
|
+
explicit compatibility control. Stdout artifacts always suppress the host
|
|
58
|
+
receipt; declaring `receipt: "render"` with `channel: "stdout"` is rejected at
|
|
59
|
+
registration so redirection, `jq`, and binary output remain clean by
|
|
60
|
+
construction.
|
|
61
|
+
|
|
62
|
+
The host does not decode, re-encode, buffer, or inspect stdout artifact bytes.
|
|
63
|
+
Consequently NUL bytes and non-UTF-8 payloads pass through unchanged. The
|
|
64
|
+
extension owns media correctness and stream completion; the host owns only the
|
|
65
|
+
post-handler receipt policy.
|
|
66
|
+
|
|
67
|
+
## Shared NDJSON framing
|
|
68
|
+
|
|
69
|
+
SDK-built producers can use `serializeNdjsonStream(rows, trailer)` to append one
|
|
70
|
+
typed `pm.stream.trailer` after a bounded row batch. It supplies one stable
|
|
71
|
+
place for counts, continuation cursors, source identity, and constant-size
|
|
72
|
+
producer metadata without adding per-row overhead.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SDK context coordination primitives
|
|
2
2
|
|
|
3
|
-
Trackers: [pm-e200](../.agents/pm/features/pm-e200.toon), [pm-4ri6](../.agents/pm/features/pm-4ri6.toon), and [pm-hcrmye](../.agents/pm/issues/pm-hcrmye.toon).
|
|
3
|
+
Trackers: [pm-e200](../.agents/pm/features/pm-e200.toon), [pm-ez1dfg](../.agents/pm/tasks/pm-ez1dfg.toon), [pm-4ri6](../.agents/pm/features/pm-4ri6.toon), and [pm-hcrmye](../.agents/pm/issues/pm-hcrmye.toon).
|
|
4
4
|
|
|
5
5
|
`pm` treats project management as context management. These primitives let an
|
|
6
6
|
agent learn what changed, avoid creating redundant work, and keep that work
|
|
@@ -26,38 +26,72 @@ Read committed history facts as newline-delimited JSON:
|
|
|
26
26
|
pm events --type create --author agent-a --limit 100
|
|
27
27
|
pm events --since <cursor> --item pm-abcd
|
|
28
28
|
pm events --since <cursor> --follow --interval-ms 250
|
|
29
|
+
pm events --cursor-mode row --since <cursor>
|
|
29
30
|
```
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
`patch_count
|
|
32
|
+
By default, event rows carry `item_id`, `version`, `ts`, `author`, `type`, and
|
|
33
|
+
`patch_count`, followed by one `pm.stream.trailer` record with `count`,
|
|
34
|
+
`has_more`, `next_cursor`, and `source`. Persist the trailer cursor only after
|
|
35
|
+
the batch is durable. A crash before cursor persistence can replay the last
|
|
36
|
+
batch repeatedly, including across multiple crashes. Consumers must process
|
|
37
|
+
idempotently or deduplicate replays. `--cursor-mode row` preserves the previous
|
|
38
|
+
shape with one `cursor` per event and no trailer for consumers that checkpoint
|
|
39
|
+
every row. Already issued version-1 cursors remain accepted by `--since`.
|
|
40
|
+
|
|
41
|
+
Node runtimes use the rebuildable SQLite event projection. Runtimes such as Bun
|
|
42
|
+
that do not expose `node:sqlite` transparently scan the authoritative history
|
|
43
|
+
streams with the same ordering, filters, pagination, and cursor contract; pages
|
|
44
|
+
identify that path with `source: "authoritative_history"`.
|
|
45
|
+
|
|
46
|
+
`--full` also includes the complete authoritative history entry.
|
|
33
47
|
`--type`, `--author`, and `--item` accept repeatable or comma-separated values.
|
|
34
48
|
`--since` accepts either a cursor or an ISO timestamp. The CLI emits only event
|
|
35
|
-
rows, so
|
|
49
|
+
rows and the typed terminal record, so consumers can distinguish data from
|
|
50
|
+
recovery metadata without relying on position alone. Under `--follow`, every
|
|
51
|
+
non-empty page ends at the same batch boundary and an empty boundary is emitted
|
|
52
|
+
as an idle heartbeat.
|
|
36
53
|
|
|
37
54
|
The public SDK provides bounded pages and an abortable async iterator:
|
|
38
55
|
|
|
39
56
|
```ts
|
|
40
57
|
import {
|
|
41
58
|
listMutationEvents,
|
|
59
|
+
subscribeMutationEventBatches,
|
|
42
60
|
subscribeMutationEvents,
|
|
43
61
|
} from "@unbrained/pm-cli/sdk";
|
|
44
62
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
const eventTypes = ["create", "update"] as const;
|
|
64
|
+
let cursor: string | undefined;
|
|
65
|
+
let hasMore = true;
|
|
66
|
+
while (hasMore) {
|
|
67
|
+
const page = await listMutationEvents({
|
|
68
|
+
pmRoot,
|
|
69
|
+
type: eventTypes,
|
|
70
|
+
limit: 100,
|
|
71
|
+
...(cursor === undefined ? {} : { since: cursor }),
|
|
72
|
+
});
|
|
73
|
+
await consumeBatch(page.events);
|
|
74
|
+
await persistCursor(page.next_cursor);
|
|
75
|
+
cursor = page.next_cursor;
|
|
76
|
+
hasMore = page.has_more;
|
|
77
|
+
}
|
|
50
78
|
|
|
51
79
|
const controller = new AbortController();
|
|
52
|
-
for await (const
|
|
80
|
+
for await (const batch of subscribeMutationEventBatches({
|
|
53
81
|
pmRoot,
|
|
54
|
-
|
|
82
|
+
type: eventTypes,
|
|
83
|
+
...(cursor === undefined ? {} : { since: cursor }),
|
|
55
84
|
signal: controller.signal,
|
|
56
85
|
})) {
|
|
57
|
-
await
|
|
86
|
+
await consumeBatch(batch.events);
|
|
87
|
+
await persistCursor(batch.next_cursor);
|
|
58
88
|
}
|
|
59
89
|
```
|
|
60
90
|
|
|
91
|
+
`subscribeMutationEvents` remains the per-event compatibility iterator and
|
|
92
|
+
defaults to row cursors. `subscribeMutationEventBatches` is the token-efficient
|
|
93
|
+
coordination primitive; it exposes the same boundaries used by the CLI.
|
|
94
|
+
|
|
61
95
|
The `pm_events` MCP tool exposes the same bounded page contract. Consumers such
|
|
62
96
|
as notification packages can store `next_cursor`, catch up after a restart,
|
|
63
97
|
then follow without requiring a daemon. A pm-slack migration can replace
|
|
@@ -6,20 +6,20 @@
|
|
|
6
6
|
"scenarios": [
|
|
7
7
|
{
|
|
8
8
|
"id": "small-workspace",
|
|
9
|
-
"max_estimated_tokens":
|
|
9
|
+
"max_estimated_tokens": 552
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"id": "large-workspace",
|
|
13
|
-
"max_estimated_tokens":
|
|
13
|
+
"max_estimated_tokens": 1055
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"id": "returning-agent",
|
|
17
|
-
"max_estimated_tokens":
|
|
17
|
+
"max_estimated_tokens": 371
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
"id": "failing-command",
|
|
21
|
-
"max_estimated_tokens":
|
|
21
|
+
"max_estimated_tokens": 200
|
|
22
22
|
}
|
|
23
23
|
],
|
|
24
|
-
"composite_max_estimated_tokens":
|
|
24
|
+
"composite_max_estimated_tokens": 2178
|
|
25
25
|
}
|
package/marketplace.json
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
|
|
9
|
-
"version": "2026.8.
|
|
9
|
+
"version": "2026.8.18"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "pm-claude",
|
|
14
14
|
"source": "./plugins/pm-claude",
|
|
15
15
|
"description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
|
|
16
|
-
"version": "2026.8.
|
|
16
|
+
"version": "2026.8.18",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "unbrained",
|
|
19
19
|
"url": "https://github.com/unbraind/pm-cli"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-cli",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.18",
|
|
4
4
|
"description": "Git-native project management CLI for humans and agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.10.0",
|
|
@@ -120,7 +120,8 @@
|
|
|
120
120
|
"lint:complexity:baseline": "eslint . --suppress-rule complexity --suppress-rule sonarjs/cognitive-complexity",
|
|
121
121
|
"lint:duplicates": "jscpd --config .jscpd.json",
|
|
122
122
|
"lint:codefactor": "pnpm quality:static",
|
|
123
|
-
"quality:static": "pnpm build && node scripts/release/repository-assurance.mjs repository-static-quality --trigger ci --json && node scripts/release/audit-package-boundary.mjs && node scripts/release/package-sdk-contract-parity.mjs && node scripts/release/surface-replication-gate.mjs && node dist/cli.js assurance run tracker-context-quality --trigger ci --dry-run --json --output-budget unbounded && node scripts/release/gate-registry.mjs && node scripts/sdk-surface-snapshot.mjs --check && node scripts/bench/sdk-entrypoint-costs.mjs --check && node scripts/bench/cli-transport-floor.mjs --check && node dist/cli.js assurance run graph-composition --trigger ci --dry-run --json --output-budget unbounded && node dist/cli.js assurance run record-integrity --trigger ci --dry-run --json --output-budget unbounded",
|
|
123
|
+
"quality:static": "pnpm build && node scripts/release/repository-assurance.mjs repository-static-quality --trigger ci --json && node scripts/release/audit-package-boundary.mjs && node scripts/release/package-sdk-contract-parity.mjs && node scripts/release/surface-replication-gate.mjs && node scripts/release/command-grammar-gate.mjs && node dist/cli.js assurance run tracker-context-quality --trigger ci --dry-run --json --output-budget unbounded && node scripts/release/gate-registry.mjs && node scripts/sdk-surface-snapshot.mjs --check && node scripts/bench/sdk-entrypoint-costs.mjs --check && node scripts/bench/cli-transport-floor.mjs --check && node dist/cli.js assurance run graph-composition --trigger ci --dry-run --json --output-budget unbounded && node dist/cli.js assurance run record-integrity --trigger ci --dry-run --json --output-budget unbounded",
|
|
124
|
+
"quality:command-grammar": "pnpm build && node scripts/release/command-grammar-gate.mjs",
|
|
124
125
|
"quality:token-budget": "node scripts/release/token-budget-gate.mjs",
|
|
125
126
|
"quality:token-surface": "node scripts/measure-agent-token-surface.mjs --check",
|
|
126
127
|
"quality:token-surface:update": "pnpm build && node scripts/measure-agent-token-surface.mjs --update",
|