@unbrained/pm-cli 2026.8.14 → 2026.8.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +25 -2
  3. package/dist/cli/commander-usage.js +17 -4
  4. package/dist/cli/error-guidance.d.ts +2 -0
  5. package/dist/cli/error-guidance.js +52 -25
  6. package/dist/cli/main.js +3 -2
  7. package/dist/cli/register-mutation.js +4 -2
  8. package/dist/cli/register-operations.js +5 -5
  9. package/dist/cli-bundle/bundle-manifest.json +150 -150
  10. package/dist/cli-bundle/chunks/{chunk-TXMEUUUY.js → chunk-24GAV7XL.js} +2 -2
  11. package/dist/cli-bundle/chunks/{chunk-TMJ7URWS.js → chunk-AIM6VT2N.js} +9 -9
  12. package/dist/cli-bundle/chunks/chunk-DSWDLTDR.js +197 -0
  13. package/dist/cli-bundle/chunks/{chunk-FIW4P64F.js → chunk-J42EGKDK.js} +2 -2
  14. package/dist/cli-bundle/chunks/chunk-KIEGUBYQ.js +2 -0
  15. package/dist/cli-bundle/chunks/{chunk-SBRKH6OR.js → chunk-KLKYLSDX.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-G5JUB66K.js → chunk-LJHOAVGI.js} +59 -59
  17. package/dist/cli-bundle/chunks/{chunk-BFALV3YP.js → chunk-MEM2ZS3O.js} +2 -2
  18. package/dist/cli-bundle/chunks/chunk-QHPCJWEJ.js +35 -0
  19. package/dist/cli-bundle/chunks/{chunk-XAVMOK6B.js → chunk-WLPDLNEZ.js} +2 -2
  20. package/dist/cli-bundle/chunks/{register-list-query-T3EHHNNV.js → register-list-query-CT3LFDDN.js} +2 -2
  21. package/dist/cli-bundle/chunks/{register-mutation-E27WCLSZ.js → register-mutation-NWEVA5YS.js} +3 -3
  22. package/dist/cli-bundle/chunks/register-operations-AHIAG5KM.js +2 -0
  23. package/dist/cli-bundle/chunks/{register-setup-3YXZ444E.js → register-setup-ZJZFVAKE.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/chunk-4X57RE4U.js +2 -0
  25. package/dist/cli-bundle/focused-chunks/{chunk-XDNAW5OI.js → chunk-6XKF3PGV.js} +2 -2
  26. package/dist/cli-bundle/focused-chunks/chunk-7NJ4QYQ2.js +2 -0
  27. package/dist/cli-bundle/focused-chunks/{chunk-WCVE2NIG.js → chunk-EXZA4257.js} +2 -2
  28. package/dist/cli-bundle/focused-chunks/chunk-ITAUHSO6.js +50 -0
  29. package/dist/cli-bundle/focused-chunks/{chunk-4DQ2YERC.js → chunk-KLVUMNXJ.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-K7RWWOAG.js → chunk-KT5XMYSX.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/{chunk-PPFGQDSI.js → chunk-KTKH4IMG.js} +2 -2
  32. package/dist/cli-bundle/focused-chunks/chunk-M67F5AIN.js +8 -0
  33. package/dist/cli-bundle/focused-chunks/{chunk-KSEDUWVZ.js → chunk-NSPYTG6G.js} +2 -2
  34. package/dist/cli-bundle/focused-chunks/chunk-OKA6ELTL.js +2 -0
  35. package/dist/cli-bundle/focused-chunks/chunk-PUISBOPP.js +2 -0
  36. package/dist/cli-bundle/focused-chunks/chunk-QLNMCESQ.js +155 -0
  37. package/dist/cli-bundle/focused-chunks/{chunk-LZ4MV3RH.js → chunk-SLKC6QLJ.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/chunk-U65UC4G3.js +2 -0
  39. package/dist/cli-bundle/focused-chunks/{chunk-KFSZ3BP6.js → chunk-WTSER4WJ.js} +6 -6
  40. package/dist/cli-bundle/focused-chunks/{chunk-YOOI3UZX.js → chunk-ZMFXQ7VF.js} +2 -2
  41. package/dist/cli-bundle/main.js +13 -13
  42. package/dist/cli-bundle/sdk-authoring.js +1 -1
  43. package/dist/cli-bundle/sdk-contracts.js +1 -1
  44. package/dist/cli-bundle/sdk-core.js +32 -35
  45. package/dist/cli-bundle/sdk-governance.js +1 -1
  46. package/dist/cli-bundle/sdk-graph.js +1 -1
  47. package/dist/cli-bundle/sdk-merge.js +32 -31
  48. package/dist/cli-bundle/sdk-query.js +1 -1
  49. package/dist/cli-bundle/sdk-runtime.js +1 -1
  50. package/dist/cli-bundle/sdk-testing.js +1 -1
  51. package/dist/cli-bundle/sdk.js +2 -2
  52. package/dist/core/diagnostics/remediation.js +7 -2
  53. package/dist/core/extensions/reserved-host-flags.js +3 -2
  54. package/dist/core/history/replay.d.ts +14 -1
  55. package/dist/core/history/replay.js +45 -8
  56. package/dist/core/output/output.d.ts +2 -0
  57. package/dist/core/output/output.js +3 -2
  58. package/dist/core/shared/command-types.d.ts +2 -0
  59. package/dist/core/shared/command-types.js +2 -2
  60. package/dist/core/shared/errors.d.ts +12 -0
  61. package/dist/core/shared/errors.js +2 -2
  62. package/dist/mcp/tool-definitions.js +9 -5
  63. package/dist/sdk/agent/refusal-reachability.d.ts +61 -0
  64. package/dist/sdk/agent/refusal-reachability.js +91 -3
  65. package/dist/sdk/cli-bootstrap.d.ts +2 -0
  66. package/dist/sdk/cli-bootstrap.js +7 -2
  67. package/dist/sdk/cli-contracts/completeness.js +3 -2
  68. package/dist/sdk/cli-contracts/flag-contracts.js +3 -2
  69. package/dist/sdk/cli-contracts/registration-helpers.js +3 -2
  70. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +5 -0
  71. package/dist/sdk/cli-contracts/runtime-contracts.js +23 -7
  72. package/dist/sdk/cli-contracts/tool-parameter-tables.js +15 -5
  73. package/dist/sdk/cli-contracts/tool-schema.js +10 -3
  74. package/dist/sdk/cli-program.js +3 -2
  75. package/dist/sdk/core.d.ts +2 -2
  76. package/dist/sdk/core.js +3 -3
  77. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +26 -2
  78. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -26
  79. package/dist/sdk/governance/assurance-action.d.ts +7 -1
  80. package/dist/sdk/governance/assurance-action.js +7 -6
  81. package/dist/sdk/governance/assurance-mutation-error.d.ts +42 -1
  82. package/dist/sdk/governance/assurance-mutation-error.js +27 -3
  83. package/dist/sdk/governance/assurance-runtime.js +12 -11
  84. package/dist/sdk/governance/assurance.d.ts +9 -0
  85. package/dist/sdk/governance/assurance.js +80 -14
  86. package/dist/sdk/governance/extension-host-version.d.ts +25 -0
  87. package/dist/sdk/governance/extension-host-version.js +105 -0
  88. package/dist/sdk/governance/health.d.ts +32 -1
  89. package/dist/sdk/governance/health.js +119 -27
  90. package/dist/sdk/governance/provenance-health.d.ts +27 -0
  91. package/dist/sdk/governance/provenance-health.js +95 -3
  92. package/dist/sdk/governance/validate.js +7 -8
  93. package/dist/sdk/governance.d.ts +6 -0
  94. package/dist/sdk/governance.js +8 -2
  95. package/dist/sdk/history-repair.d.ts +13 -1
  96. package/dist/sdk/history-repair.js +62 -18
  97. package/dist/sdk/linked-artifacts.js +16 -5
  98. package/dist/sdk/pagination.d.ts +15 -0
  99. package/dist/sdk/pagination.js +9 -5
  100. package/dist/sdk/query/context.d.ts +5 -1
  101. package/dist/sdk/query/context.js +14 -5
  102. package/dist/sdk/read-output/continuation.d.ts +11 -0
  103. package/dist/sdk/read-output/continuation.js +132 -0
  104. package/dist/sdk/read-output-budget.d.ts +1 -1
  105. package/dist/sdk/read-output-budget.js +14 -10
  106. package/dist/sdk/read-output-contracts.d.ts +66 -2
  107. package/dist/sdk/read-output-contracts.js +183 -19
  108. package/dist/sdk/read-output-rows.d.ts +2 -0
  109. package/dist/sdk/read-output-rows.js +15 -2
  110. package/dist/sdk/runtime-input.js +4 -2
  111. package/docs/ASSURANCE.md +59 -2
  112. package/docs/COMMANDS.md +8 -2
  113. package/docs/READ_OUTPUT_CONTRACTS.md +49 -8
  114. package/docs/RELEASING.md +42 -5
  115. package/docs/SDK_CONTEXT_INTEGRITY.md +64 -2
  116. package/marketplace.json +2 -2
  117. package/package.json +3 -3
  118. package/packages/pm-beads/package.json +1 -1
  119. package/packages/pm-calendar/package.json +1 -1
  120. package/packages/pm-command-kit/package.json +1 -1
  121. package/packages/pm-digital-twin/package.json +1 -1
  122. package/packages/pm-governance-audit/package.json +1 -1
  123. package/packages/pm-guide-shell/package.json +1 -1
  124. package/packages/pm-kanban/package.json +1 -1
  125. package/packages/pm-lifecycle-hooks/package.json +1 -1
  126. package/packages/pm-linked-test-adapters/package.json +1 -1
  127. package/packages/pm-search-advanced/package.json +1 -1
  128. package/packages/pm-templates/package.json +1 -1
  129. package/packages/pm-todos/package.json +1 -1
  130. package/packages/pm-vcs/package.json +1 -1
  131. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  132. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  133. package/sdk/public-surface.json +1133 -187
  134. package/dist/cli-bundle/chunks/chunk-BBOFSVAK.js +0 -197
  135. package/dist/cli-bundle/chunks/chunk-YAMTJL6Y.js +0 -34
  136. package/dist/cli-bundle/chunks/chunk-YSVSMJ2B.js +0 -2
  137. package/dist/cli-bundle/chunks/register-operations-4R6I7CPY.js +0 -2
  138. package/dist/cli-bundle/focused-chunks/chunk-F43TT2QQ.js +0 -8
  139. package/dist/cli-bundle/focused-chunks/chunk-KYUQGTSB.js +0 -2
  140. package/dist/cli-bundle/focused-chunks/chunk-PGXJQLCT.js +0 -155
  141. package/dist/cli-bundle/focused-chunks/chunk-Q4YY3XNF.js +0 -2
  142. package/dist/cli-bundle/focused-chunks/chunk-QK753U3U.js +0 -46
  143. package/dist/cli-bundle/focused-chunks/chunk-QUMB2J27.js +0 -2
  144. package/dist/cli-bundle/focused-chunks/chunk-SM7MTG27.js +0 -2
  145. package/dist/cli-bundle/focused-chunks/chunk-ZM6TZVHC.js +0 -2
@@ -4,7 +4,7 @@
4
4
  * Implements the pm context command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="757a0349-9fb6-579d-ab29-fabaad790ce4")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ee5279f2-7489-59fb-8f96-f2e035434cce")}catch(e){}}();
8
8
  import { SETTINGS_DEFAULTS, EXIT_CODE, PmCliError, compareTimestampStrings, nowIso, isTerminalStatus, normalizeStatusForRegistry, normalizeStatusInput, resolveRuntimeStatusRegistry, resolvePmRoot, readSettings, resolveAuthor, discoverExtensions, } from "../runtime-primitives.js";
9
9
  import { collectDependencyBlockedIds, resolveItemBlockers, } from "../actionability.js";
10
10
  import { CONTEXT_DEPTH_VALUES, CONTEXT_SECTION_VALUES, } from "../../types/index.js";
@@ -455,17 +455,22 @@ export function toContextPackingSummary(report) {
455
455
  };
456
456
  }
457
457
  /** Project a full scorer report onto the low-token command explanation shape. */
458
- export function toContextRankingSummary(report, featureStore) {
458
+ export function toContextRankingSummary(report, featureStore, servedItemIds) {
459
+ const ranked = servedItemIds === undefined
460
+ ? report.ranked
461
+ : report.ranked.filter((entry) => servedItemIds.has(entry.id));
459
462
  return {
460
463
  model: report.model,
461
464
  available_signals: report.available_signals,
462
- items: report.ranked.map((entry) => ({
465
+ items: ranked.map((entry) => ({
463
466
  id: entry.id,
464
467
  rank: entry.rank,
465
468
  baseline_rank: entry.baseline_rank,
466
469
  score: entry.score,
467
470
  contributions: entry.contributions,
468
471
  })),
472
+ candidate_count: report.ranked.length,
473
+ omitted_count: report.ranked.length - ranked.length,
469
474
  ...(featureStore
470
475
  ? {
471
476
  feature_store: {
@@ -1659,7 +1664,11 @@ export async function runContext(options, global) {
1659
1664
  attachOptionalContextSections(result, sections, focusGroups.featureStore.warning_details);
1660
1665
  applyContextTagProjection(result, options.noTags === true);
1661
1666
  if (options.explainRanking === true) {
1662
- result.ranking = toContextRankingSummary(focusGroups.ranking, focusGroups.featureStore);
1667
+ result.ranking = toContextRankingSummary(focusGroups.ranking, focusGroups.featureStore, new Set([
1668
+ ...focusGroups.highLevel,
1669
+ ...focusGroups.lowLevel,
1670
+ ...focusGroups.blockedFallback,
1671
+ ].map((entry) => entry.id)));
1663
1672
  result.packing = toContextPackingSummary(focusGroups.packing);
1664
1673
  }
1665
1674
  applyContextFocusProjection(result, runtime.focusFields);
@@ -1670,4 +1679,4 @@ export async function runContext(options, global) {
1670
1679
  return result;
1671
1680
  }
1672
1681
  //# sourceMappingURL=context.js.map
1673
- //# debugId=757a0349-9fb6-579d-ab29-fabaad790ce4
1682
+ //# debugId=ee5279f2-7489-59fb-8f96-f2e035434cce
@@ -0,0 +1,11 @@
1
+ import type { PmReadOutputCursorEnvelope, PmReadOutputSurface } from "../read-output-contracts.js";
2
+ /** Fingerprint stable row identities without including volatile observation fields. */
3
+ export declare function readOutputCollectionFingerprint(path: string, value: unknown[] | Record<string, unknown>): string;
4
+ /** Encode one stable declared-row continuation for CLI, SDK, and MCP callers. */
5
+ export declare function encodeReadOutputContinuationCursor(cursor: Omit<PmReadOutputCursorEnvelope, "version">): string;
6
+ /** Decode and validate one universal declared-row continuation cursor. */
7
+ export declare function decodeReadOutputContinuationCursor(raw: string): PmReadOutputCursorEnvelope;
8
+ /** Place every non-passing assurance assertion before passing evidence. */
9
+ export declare function prioritizeAssuranceAssertions(result: Record<string, unknown>): Record<string, unknown>;
10
+ /** Validate and apply a continuation suffix to its declared row collection. */
11
+ export declare function applyReadOutputContinuation(result: Record<string, unknown>, command: PmReadOutputSurface, cursor: PmReadOutputCursorEnvelope | undefined): Record<string, unknown>;
@@ -0,0 +1,132 @@
1
+ /**
2
+ * @module sdk/read-output/continuation
3
+ *
4
+ * Encodes, validates, and applies stable continuations for declared read-output
5
+ * row collections while keeping cursor mechanics separate from dimension
6
+ * resolution and budget policy.
7
+ */
8
+
9
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8e523bbc-5745-514e-a1d8-a6ad6ece001a")}catch(e){}}();
10
+ import { createHash } from "node:crypto";
11
+ import { EXIT_CODE } from "../../core/shared/constants.js";
12
+ import { PmCliError } from "../../core/shared/errors.js";
13
+ import { resolveReadOutputSurface } from "../read-output-contracts.js";
14
+ import { readOutputRowCollections, sliceReadOutputRowCollection, } from "../read-output-rows.js";
15
+ const MAX_READ_OUTPUT_CURSOR_LENGTH = 4096;
16
+ function isRecord(value) {
17
+ return value !== null && typeof value === "object" && !Array.isArray(value);
18
+ }
19
+ /** Fingerprint stable row identities without including volatile observation fields. */
20
+ export function readOutputCollectionFingerprint(path, value) {
21
+ const identities = Array.isArray(value)
22
+ ? value.map((row, index) => {
23
+ if (!isRecord(row))
24
+ return `index:${String(index)}`;
25
+ for (const key of [
26
+ "id",
27
+ "assertion_id",
28
+ "measurement_id",
29
+ "event_id",
30
+ ]) {
31
+ const candidate = row[key];
32
+ if (typeof candidate === "string" && candidate.length > 0) {
33
+ return `${key}:${candidate}`;
34
+ }
35
+ }
36
+ return `index:${String(index)}`;
37
+ })
38
+ : Object.keys(value);
39
+ return createHash("sha256")
40
+ .update(JSON.stringify({ path, identities }))
41
+ .digest("base64url")
42
+ .slice(0, 16);
43
+ }
44
+ /** Encode one stable declared-row continuation for CLI, SDK, and MCP callers. */
45
+ export function encodeReadOutputContinuationCursor(cursor) {
46
+ return Buffer.from(JSON.stringify({
47
+ v: 1,
48
+ c: cursor.command,
49
+ p: cursor.path,
50
+ o: cursor.offset,
51
+ n: cursor.total_rows,
52
+ f: cursor.fingerprint,
53
+ }), "utf8").toString("base64url");
54
+ }
55
+ /** Decode and validate one universal declared-row continuation cursor. */
56
+ export function decodeReadOutputContinuationCursor(raw) {
57
+ if (raw.length > MAX_READ_OUTPUT_CURSOR_LENGTH) {
58
+ throw new PmCliError("The read-output continuation cursor is malformed or unsupported.", EXIT_CODE.USAGE, { code: "read_output_cursor_invalid" });
59
+ }
60
+ let candidate;
61
+ try {
62
+ candidate = JSON.parse(Buffer.from(raw, "base64url").toString("utf8"));
63
+ }
64
+ catch {
65
+ candidate = null;
66
+ }
67
+ if (!isRecord(candidate) ||
68
+ candidate.v !== 1 ||
69
+ resolveReadOutputSurface(String(candidate.c ?? "")) !== candidate.c ||
70
+ typeof candidate.p !== "string" ||
71
+ candidate.p.length === 0 ||
72
+ !Number.isSafeInteger(candidate.o) ||
73
+ candidate.o < 0 ||
74
+ !Number.isSafeInteger(candidate.n) ||
75
+ candidate.n < 1 ||
76
+ typeof candidate.f !== "string" ||
77
+ candidate.f.length === 0) {
78
+ throw new PmCliError("The read-output continuation cursor is malformed or unsupported.", EXIT_CODE.USAGE, { code: "read_output_cursor_invalid" });
79
+ }
80
+ return {
81
+ version: 1,
82
+ command: candidate.c,
83
+ path: candidate.p,
84
+ offset: candidate.o,
85
+ total_rows: candidate.n,
86
+ fingerprint: candidate.f,
87
+ };
88
+ }
89
+ /** Place every non-passing assurance assertion before passing evidence. */
90
+ export function prioritizeAssuranceAssertions(result) {
91
+ if (!Array.isArray(result.assertions))
92
+ return result;
93
+ const priority = (row) => {
94
+ if (!isRecord(row) || row.verdict === "pass")
95
+ return 4;
96
+ if (row.verdict === "retired")
97
+ return 3;
98
+ return row.enforcement === "block" ? 0 : row.enforcement === "warn" ? 1 : 2;
99
+ };
100
+ return {
101
+ ...result,
102
+ assertions: result.assertions
103
+ .map((row, index) => ({ row, index }))
104
+ .sort((left, right) => priority(left.row) - priority(right.row) || left.index - right.index)
105
+ .map(({ row }) => row),
106
+ budget_retention_policy: "verdict_priority",
107
+ };
108
+ }
109
+ /** Validate and apply a continuation suffix to its declared row collection. */
110
+ export function applyReadOutputContinuation(result, command, cursor) {
111
+ if (!cursor)
112
+ return result;
113
+ if (cursor.command !== command) {
114
+ throw new PmCliError(`The read-output cursor belongs to ${cursor.command}, not ${command}.`, EXIT_CODE.USAGE, { code: "read_output_cursor_command_mismatch" });
115
+ }
116
+ const collection = readOutputRowCollections(result).find((entry) => entry.path === cursor.path);
117
+ const totalRows = collection
118
+ ? Array.isArray(collection.value)
119
+ ? collection.value.length
120
+ : Object.keys(collection.value).length
121
+ : 0;
122
+ if (!collection ||
123
+ totalRows !== cursor.total_rows ||
124
+ cursor.offset > totalRows ||
125
+ readOutputCollectionFingerprint(cursor.path, collection.value) !==
126
+ cursor.fingerprint) {
127
+ throw new PmCliError("The read-output continuation no longer matches the declared row collection; restart the bounded read.", EXIT_CODE.USAGE, { code: "read_output_cursor_stale" });
128
+ }
129
+ return sliceReadOutputRowCollection(result, cursor.path, cursor.offset);
130
+ }
131
+ //# sourceMappingURL=continuation.js.map
132
+ //# debugId=8e523bbc-5745-514e-a1d8-a6ad6ece001a
@@ -10,4 +10,4 @@ export declare function estimateReadOutputTokens(result: unknown): number;
10
10
  /** Update a receipt to the fixed-point estimate of the result containing it. */
11
11
  export declare function updateReadOutputReceiptEstimate(result: Record<string, unknown>, receipt: PmReadOutputReceipt): void;
12
12
  /** Compact strings and rows in place, then return the final exact estimate. */
13
- export declare function compactReadOutputToBudget(result: Record<string, unknown>, receipt: PmReadOutputReceipt, budget: number): Record<string, unknown>;
13
+ export declare function compactReadOutputToBudget(result: Record<string, unknown>, receipt: PmReadOutputReceipt, budget: number, minimumRowsByPath?: ReadonlyMap<string, number>): Record<string, unknown>;
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="cc595424-0176-5920-8f4c-d935e6a546ce")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="737ac274-c165-5d1a-8b8e-cb5d57a81c46")}catch(e){}}();
3
3
  import { countReadOutputRows, readOutputBudgetCollections, } from "./read-output-rows.js";
4
4
  const MAX_ESTIMATE_ITERATIONS = 8;
5
5
  const MAX_COMPACTION_ITERATIONS = 64;
@@ -42,15 +42,18 @@ export function updateReadOutputReceiptEstimate(result, receipt) {
42
42
  receipt.estimated_tokens = estimate;
43
43
  }
44
44
  /** Reduce the largest row collection until the budget fits or no rows can move. */
45
- function compactRowsToBudget(result, receipt, budget) {
45
+ function compactRowsToBudget(result, receipt, budget, minimumRowsByPath) {
46
46
  for (let iteration = 0; iteration < MAX_COMPACTION_ITERATIONS; iteration += 1) {
47
47
  updateReadOutputReceiptEstimate(result, receipt);
48
48
  if (receipt.estimated_tokens <= budget)
49
49
  return;
50
50
  const candidate = readOutputBudgetCollections(result)
51
- .filter((collection) => (Array.isArray(collection.value)
52
- ? collection.value.length
53
- : Object.keys(collection.value).length) > 1)
51
+ .filter((collection) => {
52
+ const length = Array.isArray(collection.value)
53
+ ? collection.value.length
54
+ : Object.keys(collection.value).length;
55
+ return (length > Math.max(1, minimumRowsByPath.get(collection.path) ?? 0));
56
+ })
54
57
  .map((collection) => ({
55
58
  collection,
56
59
  length: Array.isArray(collection.value)
@@ -61,12 +64,13 @@ function compactRowsToBudget(result, receipt, budget) {
61
64
  left.collection.path.localeCompare(right.collection.path))[0]?.collection;
62
65
  if (!candidate)
63
66
  return;
67
+ const minimumRows = Math.max(1, minimumRowsByPath.get(candidate.path) ?? 0);
64
68
  if (Array.isArray(candidate.value)) {
65
- candidate.value.splice(-Math.max(1, Math.ceil(candidate.value.length / 2)));
69
+ candidate.value.splice(-Math.min(candidate.value.length - minimumRows, Math.max(1, Math.ceil(candidate.value.length / 2))));
66
70
  }
67
71
  else {
68
72
  const keys = Object.keys(candidate.value);
69
- for (const key of keys.slice(-Math.max(1, Math.ceil(keys.length / 2)))) {
73
+ for (const key of keys.slice(-Math.min(keys.length - minimumRows, Math.max(1, Math.ceil(keys.length / 2))))) {
70
74
  delete candidate.value[key];
71
75
  }
72
76
  }
@@ -82,14 +86,14 @@ function compactRowsToBudget(result, receipt, budget) {
82
86
  }
83
87
  }
84
88
  /** Compact strings and rows in place, then return the final exact estimate. */
85
- export function compactReadOutputToBudget(result, receipt, budget) {
89
+ export function compactReadOutputToBudget(result, receipt, budget, minimumRowsByPath = new Map()) {
86
90
  const stringCompactionState = { compacted: false };
87
91
  const compacted = compactStrings(result, stringCompactionState);
88
92
  receipt.strings_compacted = stringCompactionState.compacted;
89
93
  compacted.read_output = receipt;
90
- compactRowsToBudget(compacted, receipt, budget);
94
+ compactRowsToBudget(compacted, receipt, budget, minimumRowsByPath);
91
95
  updateReadOutputReceiptEstimate(compacted, receipt);
92
96
  return compacted;
93
97
  }
94
98
  //# sourceMappingURL=read-output-budget.js.map
95
- //# debugId=cc595424-0176-5920-8f4c-d935e6a546ce
99
+ //# debugId=737ac274-c165-5d1a-8b8e-cb5d57a81c46
@@ -1,3 +1,4 @@
1
+ export { decodeReadOutputContinuationCursor, encodeReadOutputContinuationCursor, } from "./read-output/continuation.js";
1
2
  import { type PmReadOutputSessionReceipt, type PmReadOutputSessionState } from "./read-output-session.js";
2
3
  /** Stable output dimensions shared by every read surface. */
3
4
  export declare const PM_READ_OUTPUT_DIMENSIONS: readonly ["include", "amount", "cost", "encoding"];
@@ -19,6 +20,8 @@ export interface PmReadOutputOptions {
19
20
  outputFormat?: "json" | "toon";
20
21
  /** Caller-carried cross-call budget and served-fact state. */
21
22
  outputSession?: string | PmReadOutputSessionState;
23
+ /** Opaque continuation returned after a budget-compacted declared row path. */
24
+ outputCursor?: string;
22
25
  /** Include row selector and encoding discovery metadata. */
23
26
  outputRowContract?: boolean;
24
27
  }
@@ -54,6 +57,8 @@ export interface PmReadOutputSurfaceContract {
54
57
  dimensions: Record<PmReadOutputDimension, PmReadOutputDimensionContract>;
55
58
  /** Deterministic precedence from strongest caller declaration to fallback. */
56
59
  precedence: readonly ["canonical", "legacy", "intent", "default"];
60
+ /** Stable policy used before budget compaction selects retained rows. */
61
+ budget_retention_policy: "ordered_prefix" | "verdict_priority";
57
62
  }
58
63
  /** Source that selected an effective output dimension. */
59
64
  export type PmReadOutputDimensionSource = "canonical" | "legacy" | "intent" | "default";
@@ -128,8 +133,63 @@ export interface PmReadOutputTruncationDisclosure {
128
133
  overridden_dimensions: PmReadOutputDimension[];
129
134
  /** Declared or nested collection paths reduced by budget degradation. */
130
135
  compacted_row_paths: string[];
136
+ /** Whether next_cursor was moved back to the last row that survived compaction. */
137
+ continuation_cursor_rebased: boolean;
138
+ /** Whether at least one declared row collection can be resumed within the budget. */
139
+ continuation_available: boolean;
140
+ /** Maximum next-page useful-result budget relative to the current budget. */
141
+ recovery_budget_multiplier: 1;
142
+ /** Bounded continuation instructions for every compacted declared row path. */
143
+ continuations: PmReadOutputContinuation[];
131
144
  /** Executable recovery instruction for retrieving the complete result. */
132
145
  restore_with: string;
146
+ /** Transport-specific machine recovery options. */
147
+ recovery: {
148
+ /** Opaque value supplied through each declared transport binding. */
149
+ cursor: string;
150
+ /** CLI option accepting cursor. */
151
+ cli: "--output-cursor";
152
+ /** SDK option field accepting cursor. */
153
+ sdk: "outputCursor";
154
+ /** MCP input field accepting cursor. */
155
+ mcp: "outputCursor";
156
+ } | {
157
+ cli: string;
158
+ sdk: {
159
+ outputBudget: number;
160
+ };
161
+ mcp: {
162
+ outputBudget: number;
163
+ };
164
+ };
165
+ }
166
+ /** One resumable declared-row collection withheld by budget compaction. */
167
+ export interface PmReadOutputContinuation {
168
+ /** Dot-delimited declared row path being resumed. */
169
+ path: string;
170
+ /** Opaque cursor accepted by CLI, SDK, and MCP outputCursor inputs. */
171
+ cursor: string;
172
+ /** Rows retained from this path in the current response. */
173
+ retained_rows: number;
174
+ /** Rows remaining after the current response. */
175
+ remaining_rows: number;
176
+ /** Total rows in the stable collection snapshot. */
177
+ total_rows: number;
178
+ }
179
+ /** Versioned, command-bound cursor payload for one stable declared row collection. */
180
+ export interface PmReadOutputCursorEnvelope {
181
+ /** Serialized cursor format version. */
182
+ version: 1;
183
+ /** Canonical read surface that produced the cursor. */
184
+ command: PmReadOutputSurface;
185
+ /** Dot-delimited declared row path being continued. */
186
+ path: string;
187
+ /** Zero-based index of the first withheld row. */
188
+ offset: number;
189
+ /** Stable pre-projection denominator for the row collection. */
190
+ total_rows: number;
191
+ /** Stable identity fingerprint used to refuse stale continuation. */
192
+ fingerprint: string;
133
193
  }
134
194
  /** Result returned when the requested cost ceiling cannot fit useful content. */
135
195
  export interface PmReadOutputBudgetExceeded {
@@ -141,6 +201,10 @@ export interface PmReadOutputBudgetExceeded {
141
201
  reason: "requested_budget_infeasible";
142
202
  /** Human- and agent-readable recovery instruction. */
143
203
  restore_with: string;
204
+ /** Transport-specific machine recovery options. */
205
+ recovery: {
206
+ outputBudget: "unbounded";
207
+ };
144
208
  };
145
209
  /** Exact receipt for the bounded omission envelope. */
146
210
  read_output: PmReadOutputReceipt;
@@ -154,11 +218,11 @@ export type PmReadOutputResult<Result> = (Result & {
154
218
  read_session?: PmReadOutputSessionReceipt;
155
219
  });
156
220
  /** Select the omission-aware result type when an option shape can request a budget. */
157
- export type PmReadOutputResultFor<Result, Options> = "outputBudget" extends keyof Options ? PmReadOutputResult<Result> : "outputSession" extends keyof Options ? PmReadOutputResult<Result> : Result;
221
+ export type PmReadOutputResultFor<Result, Options> = "outputBudget" extends keyof Options ? PmReadOutputResult<Result> : "outputSession" extends keyof Options ? PmReadOutputResult<Result> : "outputCursor" extends keyof Options ? PmReadOutputResult<Result> : Result;
158
222
  /** Canonical CLI flags that opt a read invocation into universal output shaping. */
159
223
  export declare const PM_READ_OUTPUT_OPTION_FLAGS: readonly string[];
160
224
  /** Canonical control that composes the four per-call dimensions across reads. */
161
- export declare const PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS: readonly ["--output-session", "--output-row-contract"];
225
+ export declare const PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS: readonly ["--output-session", "--output-cursor", "--output-row-contract"];
162
226
  /** Universal output contract for every built-in read surface. */
163
227
  export declare const PM_READ_OUTPUT_SURFACE_CONTRACTS: readonly PmReadOutputSurfaceContract[];
164
228
  /** Resolve a command or list/context alias to its canonical read-output surface. */