@unbrained/pm-cli 2026.9.17 → 2026.9.19
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/CHANGELOG.md +49 -0
- package/dist/cli/invocation-profile.d.ts +26 -0
- package/dist/cli/invocation-profile.js +3 -0
- package/dist/cli/register-operations.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +149 -149
- package/dist/cli-bundle/chunks/{chunk-LD2FH2YE.js → chunk-7CN53F4S.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-AACGU5IA.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-Q6KPZGMP.js → chunk-CCLWCESZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-T526C5DX.js → chunk-J7NP7QLW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UF75LUAK.js → chunk-K4VAU4HU.js} +63 -63
- package/dist/cli-bundle/chunks/chunk-KHN4NMKT.js +238 -0
- package/dist/cli-bundle/chunks/{chunk-YZXB4XGA.js → chunk-KYG2QKNY.js} +29 -29
- package/dist/cli-bundle/chunks/{chunk-CPFBDM53.js → chunk-OQS2Y6VN.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-G2IJF244.js → chunk-QA4GUEKJ.js} +20 -20
- package/dist/cli-bundle/chunks/chunk-QTHR3LXF.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-5ZY4WE3F.js → chunk-RVMDPIGD.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-WASMH647.js +8 -0
- package/dist/cli-bundle/chunks/{register-list-query-ISM35VIX.js → register-list-query-RMZNHSII.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-KHMBJJS6.js → register-mutation-HJGSGX3H.js} +2 -2
- package/dist/cli-bundle/chunks/register-operations-LBEMFUMM.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-YAURJMY5.js → register-setup-MU557JAA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-G4TKJZ4A.js → chunk-5SZ4JSPZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-NOK652OP.js → chunk-7Y7PAC56.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5KYHDFDN.js → chunk-ARK4FIO4.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-LNM3BS45.js → chunk-CJ4QA4RW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-I32L3FWW.js +12 -0
- package/dist/cli-bundle/focused-chunks/{chunk-267N774W.js → chunk-I4WDON3K.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-7ZC4CKOX.js → chunk-IKPR4VVN.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-J3GN4SQT.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-GKSAMNBG.js → chunk-OOZHQFBF.js} +16 -16
- package/dist/cli-bundle/focused-chunks/{chunk-JZSLDLR4.js → chunk-P4BA7OX7.js} +27 -26
- package/dist/cli-bundle/focused-chunks/chunk-QL4MO5M2.js +30 -0
- package/dist/cli-bundle/focused-chunks/chunk-TDHVROGL.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-V3YMNAO7.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-YDFEWXXZ.js +59 -0
- package/dist/cli-bundle/focused-chunks/{chunk-WUMGGQYN.js → chunk-ZDBKYZFE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-BFUXTNZU.js → chunk-ZI2YBJFH.js} +2 -2
- package/dist/cli-bundle/main.js +2 -2
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +25 -25
- 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 +41 -41
- 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 +8 -8
- package/dist/cli.js +1 -1
- package/dist/core/checkpoint/mutation-checkpoint.d.ts +1 -1
- package/dist/core/checkpoint/mutation-checkpoint.js +2 -2
- package/dist/core/config/nested-settings.js +1 -1
- package/dist/core/fs/atomic-create.d.ts +7 -0
- package/dist/core/fs/atomic-create.js +2 -0
- package/dist/core/history/history.js +1 -1
- package/dist/core/schema/runtime-schema.d.ts +1 -1
- package/dist/core/schema/runtime-schema.js +2 -2
- package/dist/core/session/session-state.js +1 -1
- package/dist/core/shared/secret-rules.d.ts +110 -0
- package/dist/core/shared/secret-rules.js +2 -0
- package/dist/core/store/settings-concurrency.d.ts +7 -0
- package/dist/core/store/settings-concurrency.js +2 -0
- package/dist/core/store/settings.d.ts +8 -1
- package/dist/core/store/settings.js +3 -2
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.js +1 -1
- package/dist/sdk/cli-contracts/command-aliases.js +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
- package/dist/sdk/cli-program.js +1 -1
- package/dist/sdk/context-intent-contracts.js +1 -1
- package/dist/sdk/context-relevance.js +1 -1
- package/dist/sdk/contracts.d.ts +1 -0
- package/dist/sdk/contracts.js +1 -1
- package/dist/sdk/extension/install-runtime.d.ts +1 -1
- package/dist/sdk/extension/install-runtime.js +2 -2
- package/dist/sdk/governance/health.js +1 -1
- package/dist/sdk/governance/provenance-health.d.ts +27 -0
- package/dist/sdk/governance/provenance-health.js +1 -1
- package/dist/sdk/graph/index.d.ts +1 -0
- package/dist/sdk/graph/index.js +1 -1
- package/dist/sdk/graph/query-contracts.d.ts +18 -0
- package/dist/sdk/graph/query-contracts.js +2 -0
- package/dist/sdk/graph/run.d.ts +2 -0
- package/dist/sdk/graph/run.js +1 -1
- package/dist/sdk/graph/traversal.js +1 -1
- package/dist/sdk/guide-topics.js +1 -1
- package/dist/sdk/lifecycle/event-validation-messages.d.ts +1 -1
- package/dist/sdk/lifecycle/event-validation-messages.js +1 -1
- package/dist/sdk/lifecycle-policy.js +1 -1
- package/dist/sdk/mutation-guard.d.ts +8 -1
- package/dist/sdk/mutation-guard.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/next-ready-budget.d.ts +20 -0
- package/dist/sdk/query/next-ready-budget.js +2 -0
- package/dist/sdk/query/next.d.ts +7 -2
- package/dist/sdk/query/next.js +1 -1
- package/dist/sdk/read-output-budget.d.ts +3 -1
- package/dist/sdk/read-output-budget.js +1 -1
- package/dist/sdk/read-output-contracts.js +1 -1
- package/dist/sdk/read-output-session.js +1 -1
- package/dist/sdk/test/execution.d.ts +6 -5
- package/dist/sdk/test/execution.js +2 -2
- package/dist/sdk/test/json-path.d.ts +11 -0
- package/dist/sdk/test/json-path.js +2 -0
- package/docs/BUILD_AND_RELEASE_ACCEPTANCE.md +66 -0
- package/docs/MCP_OPTION_CONFORMANCE.md +41 -0
- package/docs/MUTATION_INTEGRITY.md +36 -4
- package/docs/NEXT_SELECTION_BUDGETS.md +93 -0
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +18 -2
- package/docs/PACKED_FIRST_RUN.md +8 -4
- package/docs/PERFORMANCE.md +37 -0
- package/docs/README.md +2 -0
- package/docs/READ_OUTPUT_CONTRACTS.md +8 -4
- package/docs/SDK_AGENT_SESSION_CONTEXT.md +28 -4
- package/docs/SDK_LIFECYCLE.md +16 -2
- package/docs/WORKSPACE_CONCURRENCY.md +67 -0
- package/docs/agent-task-token-baseline.json +7 -7
- package/docs/generated/AGENT_CAPABILITY_ROUTING.md +1 -1
- package/docs/generated/AGENT_COMMAND_SURFACE.md +3 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +3 -0
- package/marketplace.json +2 -2
- package/package.json +11 -9
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/README.md +43 -2
- package/packages/pm-calendar/extensions/calendar/command-definitions.ts +52 -0
- package/packages/pm-calendar/extensions/calendar/index.ts +2 -0
- package/packages/pm-calendar/extensions/calendar/manifest.json +3 -3
- package/packages/pm-calendar/extensions/calendar/shortcuts.ts +15 -0
- 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/scripts/build-lease.mjs +43 -0
- package/scripts/build.mjs +40 -0
- package/dist/cli-bundle/chunks/chunk-C3MFMGCR.js +0 -20
- package/dist/cli-bundle/chunks/chunk-DN2RIHRN.js +0 -3
- package/dist/cli-bundle/chunks/chunk-E67MIO3Z.js +0 -8
- package/dist/cli-bundle/chunks/chunk-UJSB6NO6.js +0 -237
- package/dist/cli-bundle/chunks/register-operations-HHDROJD6.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-5FSGN4MP.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-7S7XWMXC.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-IVWUQE7T.js +0 -59
- package/dist/cli-bundle/focused-chunks/chunk-OCTTDZOU.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-OWDDVMAP.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-Z4PWEIMX.js +0 -30
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { NextResult } from "./next.js";
|
|
2
|
+
/** Evidence for a ready-selection ceiling, separate from the whole-response ceiling. */
|
|
3
|
+
export interface NextReadyBudgetReceipt {
|
|
4
|
+
/** The exact fields charged to this selection budget. */
|
|
5
|
+
scope: "recommended_and_ready";
|
|
6
|
+
/** Maximum UTF-8 bytes/4 estimate requested by the caller. */
|
|
7
|
+
budget_tokens: number;
|
|
8
|
+
/** Greater of the JSON and TOON costs of the returned selection. */
|
|
9
|
+
estimated_tokens: number;
|
|
10
|
+
/** Whether even the empty selection fits the requested budget. */
|
|
11
|
+
within_budget: boolean;
|
|
12
|
+
/** Rows removed by this budget after the independent row limit. */
|
|
13
|
+
omitted_count: number;
|
|
14
|
+
/** Whether the highest-ranked recommendation was withheld. */
|
|
15
|
+
recommendation_omitted: boolean;
|
|
16
|
+
/** Cost of the full row-limited selection, suitable for a useful retry. */
|
|
17
|
+
restore_budget_tokens: number;
|
|
18
|
+
}
|
|
19
|
+
/** Trim alternatives before the recommendation, retaining order and complete population counts. */
|
|
20
|
+
export declare function applyNextReadyBudget(result: NextResult, budget: number, hasIntentBudget: boolean): void;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!(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]="7b1a6347-904d-5c7d-a86d-23e6232b9467")}catch(e2){}})();import{estimateReadOutputTokens}from"../read-output-budget.js";function applyNextReadyBudget(result,budget,hasIntentBudget){const selection={recommended:result.recommended,ready:result.ready};const measure=()=>Math.max(estimateReadOutputTokens(selection,"json"),estimateReadOutputTokens(selection,"toon"));const originalCount=selection.ready.length+Number(selection.recommended!==null);const restoreBudget=measure();let estimate=restoreBudget;const alternatives=selection.ready;if(estimate>budget){selection.ready=[];estimate=measure()}if(restoreBudget>budget&&estimate<=budget){let lower=0;let upper=alternatives.length;while(lower<upper){const middle=Math.ceil((lower+upper)/2);selection.ready=alternatives.slice(0,middle);if(measure()<=budget)lower=middle;else upper=middle-1}selection.ready=alternatives.slice(0,lower);estimate=measure()}const recommendationOmitted=estimate>budget&&selection.recommended!==null;if(recommendationOmitted){selection.recommended=null;estimate=measure()}result.recommended=selection.recommended;result.ready=selection.ready;result.summary.recommended=selection.recommended!==null;const omittedCount=originalCount-selection.ready.length-Number(selection.recommended!==null);if(hasIntentBudget&&omittedCount===0&&estimate<=budget)return;result.truncation={...result.truncation,...omittedCount>0?{ready_total:result.summary.ready}:{},ready_budget:{scope:"recommended_and_ready",budget_tokens:budget,estimated_tokens:estimate,within_budget:estimate<=budget,omitted_count:omittedCount,recommendation_omitted:recommendationOmitted,restore_budget_tokens:restoreBudget}};if(recommendationOmitted){result.suggestions=[`Ready work exists but the selection budget omitted the recommendation. Retry pm next --token-budget ${restoreBudget}; use --output-budget to bound the entire response.`]}}export{applyNextReadyBudget};
|
|
2
|
+
//# sourceMappingURL=next-ready-budget.js.map
|
package/dist/sdk/query/next.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { type GlobalOptions } from "../runtime-primitives.js";
|
|
|
13
13
|
import type { ItemTypeRegistry } from "../../core/item/type-registry.js";
|
|
14
14
|
import type { ItemStatus } from "../../types/index.js";
|
|
15
15
|
import { type ContextFocusItem, type ContextRankingSummary, type ContextPackingSummary } from "./context.js";
|
|
16
|
+
import { type NextReadyBudgetReceipt } from "./next-ready-budget.js";
|
|
16
17
|
/** Supported values accepted by the next output contract. */
|
|
17
18
|
export declare const NEXT_OUTPUT_VALUES: readonly ["markdown", "toon", "json"];
|
|
18
19
|
/** Restricts `pm next` output format values accepted by command, SDK, and storage contracts. */
|
|
@@ -45,7 +46,7 @@ export interface NextOptions {
|
|
|
45
46
|
format?: string;
|
|
46
47
|
/** Value that configures or reports explain ranking for this contract. */
|
|
47
48
|
explainRanking?: boolean;
|
|
48
|
-
/** Maximum
|
|
49
|
+
/** Maximum rendered tokens for the recommendation and ready alternatives; companion queues use outputBudget. */
|
|
49
50
|
tokenBudget?: string | number;
|
|
50
51
|
/** Include human-gated Decision items in the claimable ready queue. */
|
|
51
52
|
includeDecisions?: boolean;
|
|
@@ -152,10 +153,14 @@ export interface NextResult {
|
|
|
152
153
|
warnings?: string[];
|
|
153
154
|
/** Value that configures or reports ranking for this contract. */
|
|
154
155
|
ranking?: ContextRankingSummary;
|
|
155
|
-
/**
|
|
156
|
+
/** Advisory candidate-optimizer diagnostics; ready_budget accounts for emitted rows. */
|
|
156
157
|
packing?: ContextPackingSummary;
|
|
157
158
|
/** Explicit marker and complete counts for queues truncated by the shared section limit. */
|
|
158
159
|
truncation?: {
|
|
160
|
+
/** Complete actionable population before row and token limits. */
|
|
161
|
+
ready_total?: number;
|
|
162
|
+
/** Explicit selection-budget accounting, including infeasible empty selections. */
|
|
163
|
+
ready_budget?: NextReadyBudgetReceipt;
|
|
159
164
|
decision_needed_total?: number;
|
|
160
165
|
held_by_others_total?: number;
|
|
161
166
|
gate_needed_total?: number;
|
package/dist/sdk/query/next.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(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]="045ff474-f6d9-50c5-b554-ebc947a52443")}catch(e2){}})();import{collectBlockedByIds,computeActionabilityReport,resolveItemExecutionRole,selectActionableEntries}from"../actionability.js";import{resolveRuntimeStatusRegistry,EXIT_CODE,PmCliError,nowIso,normalizeStatusInput,normalizeStatusForRegistry,resolvePmRoot,readSettings,resolveAuthor,resolveItemTypeRegistry}from"../runtime-primitives.js";import{getActiveExtensionRegistrations}from"../../core/extensions/index.js";import{parseIntegerLimit}from"./parsers.js";import{buildChildrenByParent,collectSubtreeIds,compareCriticalItems,mergeSortedWarnings,packRankedContextItems,resolveContextTokenBudget,toContextPackingSummary,toContextRankingSummary,toContextFocusItem}from"./context.js";import{runList}from"./list.js";import{scoreContextCandidatesWithActiveExtensions}from"../context-relevance.js";import{attachContextUsageServingReceipt,collectContextUsageDeliveredItemIds,readContextUsageAffinity,recordContextUsageServing}from"../context-usage.js";import{readWorkspaceContextSignals}from"../context-signal-store.js";const NEXT_OUTPUT_VALUES=["markdown","toon","json"];const DEFAULT_NEXT_LIMIT=5;const MS_PER_DAY=24*60*60*1e3;function parseNextOutputFormat(raw){if(!raw)return void 0;const normalized=raw.trim().toLowerCase();if(!NEXT_OUTPUT_VALUES.includes(normalized)){throw new PmCliError("Next format must be one of markdown|toon|json",EXIT_CODE.USAGE)}return normalized}function resolveNextOutputFormat(options,global2){const commandFormat=parseNextOutputFormat(options.format);if(global2.json&&commandFormat&&commandFormat!=="json"){throw new PmCliError("Cannot combine --json with --format markdown|toon",EXIT_CODE.USAGE)}if(global2.json){return"json"}return commandFormat??"toon"}function parseNextLimit(raw,flag,fallback){const parsed=parseIntegerLimit(raw,flag);if(parsed===void 0||parsed<=0)return fallback;return parsed}function toNextActionableItem(entry,statusRegistry,childrenByParent,rank){return{...toContextFocusItem(entry.item,statusRegistry,childrenByParent),open_blocker_count:entry.open_blockers.length,blockers:entry.open_blockers.map(blocker=>({id:blocker.id,title:blocker.title,status:blocker.status,...blocker.external?{external:true}:{},...blocker.blocked_since?{blocked_since:blocker.blocked_since}:{},...blocker.external?{resolver:blocker.resolver??null}:{}})),unblocks:entry.unblocks,rank}}function buildRecommendationReasons(entry,statusRegistry,now,completedContainer){const item=entry.item;const reasons=[];const inProgressStatus=normalizeStatusInput("in_progress",statusRegistry);reasons.push(normalizeStatusForRegistry(item.status,statusRegistry)===inProgressStatus?"in progress \u2014 resume to finish":"open and ready to start");if(completedContainer){reasons.push("completed container \u2014 governance closeout")}reasons.push(`priority p${item.priority}${item.priority===0?" (highest)":""}`);if(typeof item.deadline==="string"&&item.deadline.trim().length>0){reasons.push(describeDeadline(item.deadline,now))}reasons.push(collectBlockedByIds(item).length>0?"all blockers resolved":"no blockers");if(typeof item.parent==="string"&&item.parent.trim().length>0){reasons.push(`advances ${item.parent.trim()}`)}if(entry.unblocks.length>0){reasons.push(`unblocks ${entry.unblocks.length} item(s)`)}return reasons}function partitionCallerOwnedReady(ready,fallbackAuthor,explicitAuthor){const caller=resolveAuthor(explicitAuthor,fallbackAuthor);const available=[];const held=[];for(const entry of ready){const assignee=typeof entry.item.assignee==="string"?entry.item.assignee.trim():"";const isForeignWork=assignee.length>0&&assignee!==caller;if(isForeignWork)held.push({id:entry.item.id,assignee});else available.push(entry)}return{available,held}}const _testOnlyNextCommand={partitionCallerOwnedReady,resolveNextCallerAuthor:(options,settingsAuthor)=>resolveNextCallerAuthor(options,settingsAuthor)};function partitionDecisionEntries(ready,includeDecisions,typeRegistry){const decisions=ready.filter(entry=>resolveItemExecutionRole(entry.item.type,typeRegistry)==="human");return{agent:includeDecisions?ready:ready.filter(entry=>resolveItemExecutionRole(entry.item.type,typeRegistry)!=="human"),decisions:includeDecisions?[]:decisions}}function describeDeadline(deadline,now){const deadlineMs=Date.parse(deadline);if(!Number.isFinite(deadlineMs)){return`deadline ${deadline.trim()}`}const dateToken=new Date(deadlineMs).toISOString().slice(0,10);const nowToken=new Date(Date.parse(now)).toISOString().slice(0,10);const days=Math.round((Date.parse(dateToken)-Date.parse(nowToken))/MS_PER_DAY);if(days<0)return`deadline ${dateToken} (overdue ${-days}d)`;if(days===0)return`deadline ${dateToken} (due today)`;return`deadline ${dateToken} (in ${days}d)`}function inProgressReadyCount(ready,statusRegistry){const inProgressStatus=normalizeStatusInput("in_progress",statusRegistry);return ready.filter(item=>normalizeStatusForRegistry(item.status,statusRegistry)===inProgressStatus).length}function hasCompletedDescendants(item,childrenByParent){return(childrenByParent.get(item.id.trim().toLowerCase())??[]).length>0}function nextListOptions(options,extra){return{type:options.type,tag:options.tag,priority:typeof options.priority==="number"?String(options.priority):options.priority,assignee:options.assignee,assigneeFilter:options.assigneeFilter,sprint:options.sprint,release:options.release,noTruncate:true,...extra}}function rankNextReadyEntries(ready,childrenByParent,statusRegistry){return[...ready].sort((left,right)=>{const leftCompletedContainer=hasCompletedDescendants(left.item,childrenByParent);const rightCompletedContainer=hasCompletedDescendants(right.item,childrenByParent);if(leftCompletedContainer!==rightCompletedContainer){return Number(leftCompletedContainer)-Number(rightCompletedContainer)}return compareCriticalItems(left.item,right.item,statusRegistry)})}function buildNextRecommendation(params){if(params.projectedReady.length===0){return null}return{...params.readyRows[0],reasons:buildRecommendationReasons(params.projectedReady[0],params.statusRegistry,params.now,params.completedContainer)}}function buildNextSuggestions(recommended,blockedRows,gateCount){if(recommended!==null){return void 0}const gateGuidance=gateCount>0?["No executable recommendation: outcome gates require verification. Inspect gate_needed, or use pm next --include-gates to opt in."]:[];if(blockedRows.length>0){const blockedWithReferences=blockedRows.find(item=>item.blockers.length>0);return[...gateGuidance,blockedWithReferences?`${blockedRows.length} item(s) are blocked; unblock the top one by closing ${blockedWithReferences.blockers.map(blocker=>blocker.id).join(", ")}`:`${blockedRows.length} item(s) are blocked; add blocker context or move the top item back to an active status`,"pm next --ready-only after a blocker closes to re-check ready work",'pm create --type Task --title "..." to add new ready work']}return[...gateGuidance,'pm create --type Task --title "..." to add a new work item',"pm list --status in_progress to review work already underway","pm context --depth deep for the full project snapshot"]}function buildNextTruncation(decisionCount,heldCount,limit){const truncation={};if(decisionCount>limit){truncation.decision_needed_total=decisionCount}if(heldCount>limit){truncation.held_by_others_total=heldCount}return Object.keys(truncation).length>0?truncation:void 0}async function attachNextUsageFeedback(params){try{const included=new Set(params.packing.included.map(entry=>entry.id));const rows=params.ranking.ranked.map(entry=>({id:entry.id,rank:entry.rank,included:included.has(entry.id)}));const rankedIds=new Set(rows.map(row=>row.id));for(const id of collectContextUsageDeliveredItemIds(params.result,"next")){if(!rankedIds.has(id)){rows.push({id,rank:rows.length+1,included:false});rankedIds.add(id)}}const receipt=await recordContextUsageServing({pmRoot:params.pmRoot,author:params.author,surface:"next",profile:params.packing.profile,rows,enabled:process.env.PM_CONTEXT_USAGE_DISABLED!=="1"});attachContextUsageServingReceipt(params.result,receipt)}catch{params.result.warnings=mergeSortedWarnings(params.result.warnings,["context_usage_feedback_write_failed"])}}async function finalizeNextResult(params){const warnings=[...new Set([...params.candidatesWarnings??[],...params.corpusWarnings??[],...params.readyRanking.warnings??[],...params.featureStore.warnings])].sort((left,right)=>left.localeCompare(right));if(warnings.length>0)params.result.warnings=warnings;if(params.explainRanking){params.result.ranking=toContextRankingSummary(params.readyRanking,params.featureStore);params.result.packing=toContextPackingSummary(params.packing)}params.result.suggestions=buildNextSuggestions(params.recommended,params.blockedRows,params.gateCount);await attachNextUsageFeedback({result:params.result,pmRoot:params.pmRoot,author:params.author,packing:params.packing,ranking:params.readyRanking});return params.result}function filterCandidatesByParentScope(candidates,corpus,parentScope){if(!parentScope){return candidates}const subtree=collectSubtreeIds(corpus,parentScope);if(!subtree.found){throw new PmCliError(`Next --parent item not found: ${parentScope}`,EXIT_CODE.NOT_FOUND)}return candidates.filter(item=>subtree.ids.has(item.id.trim().toLowerCase()))}async function rankReadyEntriesWithRelevance(rankedReady,childrenByParent,statusRegistry,now,callerAuthor,pmRoot,tokenBudget,includeContainers){const concreteReady=rankedReady.filter(entry=>!hasCompletedDescendants(entry.item,childrenByParent));const structuralReady=includeContainers||concreteReady.length===0?rankedReady:concreteReady;const usage=await readContextUsageAffinity({pmRoot,author:callerAuthor,enabled:process.env.PM_CONTEXT_USAGE_DISABLED!=="1"});const featureStore=await readWorkspaceContextSignals(structuralReady.map(entry=>entry.item),{pmRoot,storeKey:"next",statusRegistry,now,author:callerAuthor,usageAffinity:usage.affinity});const ranking=await scoreContextCandidatesWithActiveExtensions("next",featureStore.candidates);const packing=packRankedContextItems(ranking,tokenBudget,new Set,"next");const readyById=new Map(structuralReady.map(entry=>[entry.item.id,entry]));const projectedReady=ranking.ranked.map(entry=>readyById.get(entry.id)).filter(entry=>entry!==void 0);return{projectedReady,ranking,completedContainer:concreteReady.length===0&&!includeContainers,packing,featureStore}}function resolveNextCallerAuthor(options,settingsAuthor){const requestedAssignee=options.assignee?.trim();return resolveAuthor(options.callerAuthor??(requestedAssignee&&requestedAssignee.length>0?requestedAssignee:void 0),settingsAuthor)}async function runNext(options,global2){const pmRoot=resolvePmRoot(process.cwd(),global2.path);const settings=await readSettings(pmRoot);const callerAuthor=resolveNextCallerAuthor(options,settings.author_default);const statusRegistry=resolveRuntimeStatusRegistry(settings.schema);const typeRegistry=resolveItemTypeRegistry(settings,getActiveExtensionRegistrations());const now=nowIso();const limit=parseNextLimit(options.limit,"--limit",DEFAULT_NEXT_LIMIT);const tokenBudget=resolveContextTokenBudget(options.tokenBudget,Math.max(192,limit*128));const blockedLimit=parseNextLimit(options.blockedLimit,"--blocked-limit",limit);const readyOnly=options.readyOnly===true;const parentScope=typeof options.parent==="string"?options.parent.trim():"";const candidatesList=await runList(void 0,nextListOptions(options,{excludeTerminal:true}),global2);const corpusList=await runList(void 0,{excludeTerminal:false,noTruncate:true},global2);const candidates=filterCandidatesByParentScope(candidatesList.items,corpusList.items,parentScope);const corpus=corpusList.items;const report=computeActionabilityReport(candidates,corpus,statusRegistry,typeRegistry);const childrenByParent=buildChildrenByParent(corpus);const selected=selectActionableEntries(report,statusRegistry,options,typeRegistry);const callerPartition=partitionCallerOwnedReady(selected.ready,settings.author_default,callerAuthor);const rankedReady=rankNextReadyEntries(callerPartition.available,childrenByParent,statusRegistry);const rankedBlocked=[...report.blocked].sort((left,right)=>compareCriticalItems(left.item,right.item,statusRegistry));const{projectedReady,ranking:readyRanking,completedContainer,packing:readyPacking,featureStore}=await rankReadyEntriesWithRelevance(rankedReady,childrenByParent,statusRegistry,now,callerAuthor,pmRoot,tokenBudget,options.includeContainers===true);const readyRows=projectedReady.map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const blockedRows=rankedBlocked.map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const decisionRows=rankNextReadyEntries(selected.decisions,childrenByParent,statusRegistry).map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const gateRows=rankNextReadyEntries(selected.gates,childrenByParent,statusRegistry).map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const containerRows=rankNextReadyEntries(report.containers,childrenByParent,statusRegistry).map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const recommended=buildNextRecommendation({projectedReady,readyRows,statusRegistry,now,completedContainer});const truncation=buildNextTruncation(decisionRows.length,callerPartition.held.length,limit)??{};if(gateRows.length>limit)truncation.gate_needed_total=gateRows.length;if(containerRows.length>limit)truncation.containers_total=containerRows.length;const result={output_default:"toon",now,recommended,ready:readyRows.slice(1,limit+1),decision_needed:decisionRows.slice(0,limit),gate_needed:gateRows.slice(0,limit),containers:containerRows.slice(0,limit),blocked:readyOnly?[]:blockedRows.slice(0,blockedLimit),held_by_others:callerPartition.held.slice(0,limit),summary:{recommended:recommended!==null,ready:readyRows.length,blocked:blockedRows.length,in_progress:inProgressReadyCount(readyRows,statusRegistry),candidates:report.active_count,containers:report.container_count,decision_needed:decisionRows.length,gate_needed:gateRows.length,held_by_others:callerPartition.held.length},filters:{type:options.type??null,tag:options.tag??null,priority:options.priority??null,assignee:options.assignee??null,assignee_filter:options.assigneeFilter??null,sprint:options.sprint??null,release:options.release??null,parent:parentScope.length>0?parentScope:null,limit,blocked_limit:blockedLimit,ready_only:readyOnly,include_decisions:options.includeDecisions===true,include_gates:options.includeGates===true,include_containers:options.includeContainers===true,token_budget:tokenBudget},truncation:Object.keys(truncation).length>0?truncation:void 0};return finalizeNextResult({result,recommended,blockedRows,gateCount:gateRows.length,candidatesWarnings:candidatesList.warnings,corpusWarnings:corpusList.warnings,readyRanking,explainRanking:options.explainRanking===true,pmRoot,author:callerAuthor,packing:readyPacking,featureStore})}function renderNextMarkdown(result){const lines=["# pm next","",...renderNextSummaryLines(result)];for(const[title,rows]of[["Gate verification needed",result.gate_needed],["Containers",result.containers]]){if(rows&&rows.length>0)lines.push(...renderNextSection(title,rows.map(item=>`- ${formatNextLine(item)}`),""))}lines.push(...renderNextSection("Recommended",renderNextRecommendedRows(result.recommended),"No ready work."));lines.push(...renderNextSection("Decision needed",(result.decision_needed??[]).map(item=>`- ${formatNextLine(item)}`),"No human-gated decisions."));lines.push(...renderNextSection("Ready",result.ready.map(item=>`- ${formatNextLine(item)}`),"No ready items."));if(!result.filters.ready_only){lines.push(...renderNextSection("Blocked",result.blocked.map(item=>`- ${formatNextBlockedLine(item)}`),"No blocked items."))}if(result.suggestions&&result.suggestions.length>0){lines.push("## Suggestions");for(const suggestion of result.suggestions){lines.push(`- ${suggestion}`)}}return lines.join("\n").trimEnd()}function renderNextSummaryLines(result){const lines=[`- now: ${result.now}`,`- ready: ${result.summary.ready} (in_progress: ${result.summary.in_progress}), blocked: ${result.summary.blocked}, candidates: ${result.summary.candidates}`];if(result.filters.parent){lines.push(`- scope: subtree of ${result.filters.parent}`)}lines.push("");return lines}function renderNextRecommendedRows(recommended){if(!recommended){return[]}return[`- ${formatNextLine(recommended)}`,` why: ${recommended.reasons.join("; ")}`]}function renderNextSection(header,rows,emptyMessage){return[`## ${header}`,...rows.length===0?[emptyMessage]:rows,""]}function formatNextBlockedLine(item){const by=item.blockers.map(blocker=>`${blocker.id}(${blocker.status??"?"})`).join(", ");return`${formatNextLine(item)} blocked_by:${by}`}function formatNextLine(item){const deadlineToken=item.deadline??"-";const parentToken=item.parent?` parent:${item.parent}`:"";const unblocksToken=item.unblocks.length>0?` unblocks:${item.unblocks.length}`:"";const rankToken=Number.isInteger(item.rank)?`#${item.rank} `:"";return`${rankToken}${item.id} p${item.priority} ${item.status} ${item.type} deadline:${deadlineToken}${parentToken}${unblocksToken} ${item.title}`}export{NEXT_OUTPUT_VALUES,_testOnlyNextCommand,partitionDecisionEntries,renderNextMarkdown,resolveNextOutputFormat,runNext};
|
|
1
|
+
!(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]="0497aebe-9963-5025-9266-124455dd4567")}catch(e2){}})();import{collectBlockedByIds,computeActionabilityReport,resolveItemExecutionRole,selectActionableEntries}from"../actionability.js";import{resolveRuntimeStatusRegistry,EXIT_CODE,PmCliError,nowIso,normalizeStatusInput,normalizeStatusForRegistry,resolvePmRoot,readSettings,resolveAuthor,resolveItemTypeRegistry}from"../runtime-primitives.js";import{getActiveExtensionRegistrations}from"../../core/extensions/index.js";import{parseIntegerLimit}from"./parsers.js";import{buildChildrenByParent,collectSubtreeIds,compareCriticalItems,mergeSortedWarnings,packRankedContextItems,resolveContextTokenBudget,toContextPackingSummary,toContextRankingSummary,toContextFocusItem}from"./context.js";import{runList}from"./list.js";import{scoreContextCandidatesWithActiveExtensions}from"../context-relevance.js";import{attachContextUsageServingReceipt,collectContextUsageDeliveredItemIds,readContextUsageAffinity,recordContextUsageServing}from"../context-usage.js";import{applyNextReadyBudget}from"./next-ready-budget.js";import{readWorkspaceContextSignals}from"../context-signal-store.js";const NEXT_OUTPUT_VALUES=["markdown","toon","json"];const DEFAULT_NEXT_LIMIT=5;const MS_PER_DAY=24*60*60*1e3;function parseNextOutputFormat(raw){if(!raw)return void 0;const normalized=raw.trim().toLowerCase();if(!NEXT_OUTPUT_VALUES.includes(normalized)){throw new PmCliError("Next format must be one of markdown|toon|json",EXIT_CODE.USAGE)}return normalized}function resolveNextOutputFormat(options,global2){const commandFormat=parseNextOutputFormat(options.format);if(global2.json&&commandFormat&&commandFormat!=="json"){throw new PmCliError("Cannot combine --json with --format markdown|toon",EXIT_CODE.USAGE)}if(global2.json){return"json"}return commandFormat??"toon"}function parseNextLimit(raw,flag,fallback){const parsed=parseIntegerLimit(raw,flag);if(parsed===void 0||parsed<=0)return fallback;return parsed}function toNextActionableItem(entry,statusRegistry,childrenByParent,rank){return{...toContextFocusItem(entry.item,statusRegistry,childrenByParent),open_blocker_count:entry.open_blockers.length,blockers:entry.open_blockers.map(blocker=>({id:blocker.id,title:blocker.title,status:blocker.status,...blocker.external?{external:true}:{},...blocker.blocked_since?{blocked_since:blocker.blocked_since}:{},...blocker.external?{resolver:blocker.resolver??null}:{}})),unblocks:entry.unblocks,rank}}function buildRecommendationReasons(entry,statusRegistry,now,completedContainer){const item=entry.item;const reasons=[];const inProgressStatus=normalizeStatusInput("in_progress",statusRegistry);reasons.push(normalizeStatusForRegistry(item.status,statusRegistry)===inProgressStatus?"resume work":"ready");if(completedContainer){reasons.push("completed container \u2014 governance closeout")}reasons.push(`p${item.priority}${item.priority===0?" (highest)":""}`);if(typeof item.deadline==="string"&&item.deadline.trim().length>0){reasons.push(describeDeadline(item.deadline,now))}reasons.push(collectBlockedByIds(item).length>0?"all blockers resolved":"no blockers");if(typeof item.parent==="string"&&item.parent.trim().length>0){reasons.push(`advances ${item.parent.trim()}`)}if(entry.unblocks.length>0){reasons.push(`unblocks ${entry.unblocks.length} item(s)`)}return reasons}function partitionCallerOwnedReady(ready,fallbackAuthor,explicitAuthor){const caller=resolveAuthor(explicitAuthor,fallbackAuthor);const available=[];const held=[];for(const entry of ready){const assignee=typeof entry.item.assignee==="string"?entry.item.assignee.trim():"";const isForeignWork=assignee.length>0&&assignee!==caller;if(isForeignWork)held.push({id:entry.item.id,assignee});else available.push(entry)}return{available,held}}const _testOnlyNextCommand={partitionCallerOwnedReady,resolveNextCallerAuthor:(options,settingsAuthor)=>resolveNextCallerAuthor(options,settingsAuthor)};function partitionDecisionEntries(ready,includeDecisions,typeRegistry){const decisions=ready.filter(entry=>resolveItemExecutionRole(entry.item.type,typeRegistry)==="human");return{agent:includeDecisions?ready:ready.filter(entry=>resolveItemExecutionRole(entry.item.type,typeRegistry)!=="human"),decisions:includeDecisions?[]:decisions}}function describeDeadline(deadline,now){const deadlineMs=Date.parse(deadline);if(!Number.isFinite(deadlineMs)){return`deadline ${deadline.trim()}`}const dateToken=new Date(deadlineMs).toISOString().slice(0,10);const nowToken=new Date(Date.parse(now)).toISOString().slice(0,10);const days=Math.round((Date.parse(dateToken)-Date.parse(nowToken))/MS_PER_DAY);if(days<0)return`deadline ${dateToken} (overdue ${-days}d)`;if(days===0)return`deadline ${dateToken} (due today)`;return`deadline ${dateToken} (in ${days}d)`}function inProgressReadyCount(ready,statusRegistry){const inProgressStatus=normalizeStatusInput("in_progress",statusRegistry);return ready.filter(item=>normalizeStatusForRegistry(item.status,statusRegistry)===inProgressStatus).length}function hasCompletedDescendants(item,childrenByParent){return(childrenByParent.get(item.id.trim().toLowerCase())??[]).length>0}function nextListOptions(options,extra){return{type:options.type,tag:options.tag,priority:typeof options.priority==="number"?String(options.priority):options.priority,assignee:options.assignee,assigneeFilter:options.assigneeFilter,sprint:options.sprint,release:options.release,noTruncate:true,...extra}}function rankNextReadyEntries(ready,childrenByParent,statusRegistry){return[...ready].sort((left,right)=>{const leftCompletedContainer=hasCompletedDescendants(left.item,childrenByParent);const rightCompletedContainer=hasCompletedDescendants(right.item,childrenByParent);if(leftCompletedContainer!==rightCompletedContainer){return Number(leftCompletedContainer)-Number(rightCompletedContainer)}return compareCriticalItems(left.item,right.item,statusRegistry)})}function buildNextRecommendation(params){if(params.projectedReady.length===0){return null}return{...params.readyRows[0],reasons:buildRecommendationReasons(params.projectedReady[0],params.statusRegistry,params.now,params.completedContainer)}}function buildNextSuggestions(recommended,blockedRows,gateCount){if(recommended!==null){return void 0}const gateGuidance=gateCount>0?["No executable recommendation: outcome gates require verification. Inspect gate_needed, or use pm next --include-gates to opt in."]:[];if(blockedRows.length>0){const blockedWithReferences=blockedRows.find(item=>item.blockers.length>0);return[...gateGuidance,blockedWithReferences?`${blockedRows.length} item(s) are blocked; unblock the top one by closing ${blockedWithReferences.blockers.map(blocker=>blocker.id).join(", ")}`:`${blockedRows.length} item(s) are blocked; add blocker context or move the top item back to an active status`,"pm next --ready-only after a blocker closes to re-check ready work",'pm create --type Task --title "..." to add new ready work']}return[...gateGuidance,'pm create --type Task --title "..." to add a new work item',"pm list --status in_progress to review work already underway","pm context --depth deep for the full project snapshot"]}function buildNextTruncation(decisionCount,heldCount,readyCount,limit){const truncation={};if(decisionCount>limit){truncation.decision_needed_total=decisionCount}if(heldCount>limit){truncation.held_by_others_total=heldCount}if(readyCount>limit+1){truncation.ready_total=readyCount}return Object.keys(truncation).length>0?truncation:void 0}async function attachNextUsageFeedback(params){try{const included=new Set([...params.result.recommended?[params.result.recommended.id]:[],...params.result.ready.map(entry=>entry.id)]);const rows=params.ranking.ranked.map(entry=>({id:entry.id,rank:entry.rank,included:included.has(entry.id)}));const rankedIds=new Set(rows.map(row=>row.id));for(const id of collectContextUsageDeliveredItemIds(params.result,"next")){if(!rankedIds.has(id)){rows.push({id,rank:rows.length+1,included:false});rankedIds.add(id)}}const receipt=await recordContextUsageServing({pmRoot:params.pmRoot,author:params.author,surface:"next",profile:"next",rows,enabled:process.env.PM_CONTEXT_USAGE_DISABLED!=="1"});attachContextUsageServingReceipt(params.result,receipt)}catch{params.result.warnings=mergeSortedWarnings(params.result.warnings,["context_usage_feedback_write_failed"])}}async function finalizeNextResult(params){const warnings=[...new Set([...params.candidatesWarnings??[],...params.corpusWarnings??[],...params.readyRanking.warnings??[],...params.featureStore.warnings])].sort((left,right)=>left.localeCompare(right));if(warnings.length>0)params.result.warnings=warnings;params.result.suggestions=buildNextSuggestions(params.recommended,params.blockedRows,params.gateCount);if(params.tokenBudget!==void 0){applyNextReadyBudget(params.result,params.tokenBudget,params.hasIntentBudget)}if(params.explainRanking){params.result.ranking=toContextRankingSummary(params.readyRanking,params.featureStore,new Set([...params.result.recommended?[params.result.recommended.id]:[],...params.result.ready.map(entry=>entry.id)]));params.result.packing=toContextPackingSummary(packRankedContextItems(params.readyRanking,params.packingBudget,new Set,"next"))}await attachNextUsageFeedback({result:params.result,pmRoot:params.pmRoot,author:params.author,ranking:params.readyRanking});return params.result}function filterCandidatesByParentScope(candidates,corpus,parentScope){if(!parentScope){return candidates}const subtree=collectSubtreeIds(corpus,parentScope);if(!subtree.found){throw new PmCliError(`Next --parent item not found: ${parentScope}`,EXIT_CODE.NOT_FOUND)}return candidates.filter(item=>subtree.ids.has(item.id.trim().toLowerCase()))}async function rankReadyEntriesWithRelevance(rankedReady,childrenByParent,statusRegistry,now,callerAuthor,pmRoot,includeContainers){const concreteReady=rankedReady.filter(entry=>!hasCompletedDescendants(entry.item,childrenByParent));const structuralReady=includeContainers||concreteReady.length===0?rankedReady:concreteReady;const usage=await readContextUsageAffinity({pmRoot,author:callerAuthor,enabled:process.env.PM_CONTEXT_USAGE_DISABLED!=="1"});const featureStore=await readWorkspaceContextSignals(structuralReady.map(entry=>entry.item),{pmRoot,storeKey:"next",statusRegistry,now,author:callerAuthor,usageAffinity:usage.affinity});const ranking=await scoreContextCandidatesWithActiveExtensions("next",featureStore.candidates);const readyById=new Map(structuralReady.map(entry=>[entry.item.id,entry]));const projectedReady=ranking.ranked.map(entry=>readyById.get(entry.id)).filter(entry=>entry!==void 0);return{projectedReady,ranking,completedContainer:concreteReady.length===0&&!includeContainers,featureStore}}function resolveNextCallerAuthor(options,settingsAuthor){const requestedAssignee=options.assignee?.trim();return resolveAuthor(options.callerAuthor??(requestedAssignee&&requestedAssignee.length>0?requestedAssignee:void 0),settingsAuthor)}async function runNext(options,global2){const pmRoot=resolvePmRoot(process.cwd(),global2.path);const settings=await readSettings(pmRoot);const callerAuthor=resolveNextCallerAuthor(options,settings.author_default);const statusRegistry=resolveRuntimeStatusRegistry(settings.schema);const typeRegistry=resolveItemTypeRegistry(settings,getActiveExtensionRegistrations());const now=nowIso();const limit=parseNextLimit(options.limit,"--limit",DEFAULT_NEXT_LIMIT);const tokenBudget=resolveContextTokenBudget(options.tokenBudget,Math.max(192,limit*128));const blockedLimit=parseNextLimit(options.blockedLimit,"--blocked-limit",limit);const readyOnly=options.readyOnly===true;const parentScope=typeof options.parent==="string"?options.parent.trim():"";const candidatesList=await runList(void 0,nextListOptions(options,{excludeTerminal:true}),global2);const corpusList=await runList(void 0,{excludeTerminal:false,noTruncate:true},global2);const candidates=filterCandidatesByParentScope(candidatesList.items,corpusList.items,parentScope);const corpus=corpusList.items;const report=computeActionabilityReport(candidates,corpus,statusRegistry,typeRegistry);const childrenByParent=buildChildrenByParent(corpus);const selected=selectActionableEntries(report,statusRegistry,options,typeRegistry);const callerPartition=partitionCallerOwnedReady(selected.ready,settings.author_default,callerAuthor);const rankedReady=rankNextReadyEntries(callerPartition.available,childrenByParent,statusRegistry);const rankedBlocked=[...report.blocked].sort((left,right)=>compareCriticalItems(left.item,right.item,statusRegistry));const{projectedReady,ranking:readyRanking,completedContainer,featureStore}=await rankReadyEntriesWithRelevance(rankedReady,childrenByParent,statusRegistry,now,callerAuthor,pmRoot,options.includeContainers===true);const readyRows=projectedReady.map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const blockedRows=rankedBlocked.map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const decisionRows=rankNextReadyEntries(selected.decisions,childrenByParent,statusRegistry).map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const gateRows=rankNextReadyEntries(selected.gates,childrenByParent,statusRegistry).map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const containerRows=rankNextReadyEntries(report.containers,childrenByParent,statusRegistry).map((entry,index)=>toNextActionableItem(entry,statusRegistry,childrenByParent,index+1));const recommended=buildNextRecommendation({projectedReady,readyRows,statusRegistry,now,completedContainer});const truncation=buildNextTruncation(decisionRows.length,callerPartition.held.length,readyRows.length,limit)??{};if(gateRows.length>limit)truncation.gate_needed_total=gateRows.length;if(containerRows.length>limit)truncation.containers_total=containerRows.length;const result={output_default:"toon",now,recommended,ready:readyRows.slice(1,limit+1),decision_needed:decisionRows.slice(0,limit),gate_needed:gateRows.slice(0,limit),containers:containerRows.slice(0,limit),blocked:readyOnly?[]:blockedRows.slice(0,blockedLimit),held_by_others:callerPartition.held.slice(0,limit),summary:{recommended:recommended!==null,ready:readyRows.length,blocked:blockedRows.length,in_progress:inProgressReadyCount(readyRows,statusRegistry),candidates:report.active_count,containers:report.container_count,decision_needed:decisionRows.length,gate_needed:gateRows.length,held_by_others:callerPartition.held.length},filters:{type:options.type??null,tag:options.tag??null,priority:options.priority??null,assignee:options.assignee??null,assignee_filter:options.assigneeFilter??null,sprint:options.sprint??null,release:options.release??null,parent:parentScope.length>0?parentScope:null,limit,blocked_limit:blockedLimit,ready_only:readyOnly,include_decisions:options.includeDecisions===true,include_gates:options.includeGates===true,include_containers:options.includeContainers===true,token_budget:tokenBudget},truncation:Object.keys(truncation).length>0?truncation:void 0};return finalizeNextResult({result,recommended,blockedRows,gateCount:gateRows.length,candidatesWarnings:candidatesList.warnings,corpusWarnings:corpusList.warnings,readyRanking,explainRanking:options.explainRanking===true,pmRoot,author:callerAuthor,packingBudget:tokenBudget,featureStore,tokenBudget:options.tokenBudget===void 0?void 0:tokenBudget,hasIntentBudget:typeof options.for==="string"})}function renderNextMarkdown(result){const lines=["# pm next","",...renderNextSummaryLines(result)];for(const[title,rows]of[["Gate verification needed",result.gate_needed],["Containers",result.containers]]){if(rows&&rows.length>0)lines.push(...renderNextSection(title,rows.map(item=>`- ${formatNextLine(item)}`),""))}lines.push(...renderNextSection("Recommended",renderNextRecommendedRows(result.recommended),result.truncation?.ready_budget?.recommendation_omitted?"Recommendation omitted by the selection budget; ready work still exists.":"No ready work."));lines.push(...renderNextSection("Decision needed",(result.decision_needed??[]).map(item=>`- ${formatNextLine(item)}`),"No human-gated decisions."));lines.push(...renderNextSection("Ready",result.ready.map(item=>`- ${formatNextLine(item)}`),"No ready items."));if(!result.filters.ready_only){lines.push(...renderNextSection("Blocked",result.blocked.map(item=>`- ${formatNextBlockedLine(item)}`),"No blocked items."))}if(result.suggestions&&result.suggestions.length>0){lines.push("## Suggestions");for(const suggestion of result.suggestions){lines.push(`- ${suggestion}`)}}return lines.join("\n").trimEnd()}function renderNextSummaryLines(result){const lines=[`- now: ${result.now}`,`- ready: ${result.summary.ready} (in_progress: ${result.summary.in_progress}), blocked: ${result.summary.blocked}, candidates: ${result.summary.candidates}`];if(result.filters.parent){lines.push(`- scope: subtree of ${result.filters.parent}`)}lines.push("");return lines}function renderNextRecommendedRows(recommended){if(!recommended){return[]}return[`- ${formatNextLine(recommended)}`,` why: ${recommended.reasons.join("; ")}`]}function renderNextSection(header,rows,emptyMessage){return[`## ${header}`,...rows.length===0?[emptyMessage]:rows,""]}function formatNextBlockedLine(item){const by=item.blockers.map(blocker=>`${blocker.id}(${blocker.status??"?"})`).join(", ");return`${formatNextLine(item)} blocked_by:${by}`}function formatNextLine(item){const deadlineToken=item.deadline??"-";const parentToken=item.parent?` parent:${item.parent}`:"";const unblocksToken=item.unblocks.length>0?` unblocks:${item.unblocks.length}`:"";const rankToken=Number.isInteger(item.rank)?`#${item.rank} `:"";return`${rankToken}${item.id} p${item.priority} ${item.status} ${item.type} deadline:${deadlineToken}${parentToken}${unblocksToken} ${item.title}`}export{NEXT_OUTPUT_VALUES,_testOnlyNextCommand,partitionDecisionEntries,renderNextMarkdown,resolveNextOutputFormat,runNext};
|
|
2
2
|
//# sourceMappingURL=next.js.map
|
|
@@ -22,9 +22,11 @@ export interface PmReadOutputRecoveryBudget {
|
|
|
22
22
|
* the pre-compaction result, with a 25% envelope margin rounded to 100 tokens.
|
|
23
23
|
*/
|
|
24
24
|
export declare function resolveReadOutputRecoveryBudget(input: PmReadOutputRecoveryBudgetInput): PmReadOutputRecoveryBudget;
|
|
25
|
+
/** Preserve an internal row declaration across clones without charging it as emitted metadata. */
|
|
26
|
+
export declare function preserveReadOutputRowContract(source: Record<string, unknown>, target: Record<string, unknown>, suppress?: boolean): void;
|
|
25
27
|
/** Estimate UTF-8 token cost using the selected JSON/TOON renderer, or compact JSON for structured SDK calls without a renderer. */
|
|
26
28
|
export declare function estimateReadOutputTokens(result: unknown, format?: "json" | "toon"): number;
|
|
27
29
|
/** Update a receipt to the fixed-point estimate of the result containing it. */
|
|
28
30
|
export declare function updateReadOutputReceiptEstimate(result: Record<string, unknown>, receipt: PmReadOutputReceipt, format?: "json" | "toon"): void;
|
|
29
31
|
/** Compact strings and rows in place, then return the final exact estimate. */
|
|
30
|
-
export declare function compactReadOutputToBudget(result: Record<string, unknown>, receipt: PmReadOutputReceipt, budget: number, minimumRowsByPath?: ReadonlyMap<string, number>, format?: "json" | "toon"): Record<string, unknown>;
|
|
32
|
+
export declare function compactReadOutputToBudget(result: Record<string, unknown>, receipt: PmReadOutputReceipt, budget: number, minimumRowsByPath?: ReadonlyMap<string, number>, format?: "json" | "toon", finalize?: (result: Record<string, unknown>) => void): Record<string, unknown>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(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]="
|
|
1
|
+
!(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]="be0a8071-52f7-56a6-9830-a60e0d2cf29d")}catch(e2){}})();import{formatBuiltInOutput}from"../core/output/output.js";import{countReadOutputRows,readOutputBudgetCollections}from"./read-output-rows.js";const MAX_ESTIMATE_ITERATIONS=8;const MAX_COMPACTION_ITERATIONS=64;const RECOVERY_MARGIN_NUMERATOR=5;const RECOVERY_MARGIN_DENOMINATOR=4;const RECOVERY_ROUNDING_TOKENS=100;function projectReadOutputItemToBrief(command,options,result){if(command!=="get"||!isRecord(result.item)||["fields","outputInclude","output_include","outputCursor","output_cursor"].some(key=>options[key]!==void 0)||options.full===true||options.tree===true||options.depth!==void 0&&options.depth!=="standard")return void 0;const item=result.item;const sections=["linked","claim_state","schedule"];const omitted=sections.filter(key=>Object.hasOwn(result,key));const projected=Object.fromEntries(Object.entries(result).filter(([key])=>!sections.includes(key)));projected.item=Object.fromEntries(Object.entries(item).filter(([key])=>key!=="body"));if(Object.hasOwn(item,"body"))omitted.push("body");const previous=isRecord(result.omission_receipt)&&Array.isArray(result.omission_receipt.omitted_field_groups)?result.omission_receipt.omitted_field_groups:[];const groups=[...previous,...omitted.map(name=>({name,restore_with:`--fields ${name}`}))];projected.omission_receipt={has_omissions:groups.length>0,omitted_field_group_count:groups.length,omitted_field_groups:groups};return projected}function resolveReadOutputRecoveryBudget(input){const binding=Math.trunc(input.effective_budget_tokens);const measured=Math.trunc(input.measured_result_tokens);if(!Number.isSafeInteger(binding)||binding<=0||!Number.isSafeInteger(measured)||measured<=0){return{output_budget:"unbounded",recovery_budget_multiplier:null,rule_version:"v1"}}const baseline=Math.max(binding+1,measured);const withMargin=Math.ceil(baseline*RECOVERY_MARGIN_NUMERATOR/RECOVERY_MARGIN_DENOMINATOR);const rounded=Math.ceil(withMargin/RECOVERY_ROUNDING_TOKENS)*RECOVERY_ROUNDING_TOKENS;if(!Number.isSafeInteger(rounded)){return{output_budget:"unbounded",recovery_budget_multiplier:null,rule_version:"v1"}}return{output_budget:rounded,recovery_budget_multiplier:rounded/binding,rule_version:"v1"}}function preserveReadOutputRowContract(source,target,suppress=false){const descriptor=Object.getOwnPropertyDescriptor(source,"row_contract");if(descriptor&&(suppress||descriptor.enumerable===false)){Object.defineProperty(target,"row_contract",{...descriptor,enumerable:false})}}function estimateReadOutputTokens(result,format){const rendered=format===void 0?JSON.stringify(result):formatBuiltInOutput(result,format);return Math.ceil(Buffer.byteLength(rendered,"utf8")/4)}function isRecord(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)}function compactStrings(value,state){if(typeof value==="string"){if(value.length<=240)return value;state.compacted=true;return`${value.slice(0,240)}\u2026`}if(Array.isArray(value)){return value.map(entry=>compactStrings(entry,state))}if(!isRecord(value))return value;return Object.fromEntries(Object.entries(value).map(([key,entry])=>[key,compactStrings(entry,state)]))}function updateReadOutputReceiptEstimate(result,receipt,format){let estimate=receipt.estimated_tokens;for(let iteration=0;iteration<MAX_ESTIMATE_ITERATIONS;iteration+=1){receipt.estimated_tokens=estimate;const measured=estimateReadOutputTokens(result,format);if(measured===estimate)return;estimate=measured}receipt.estimated_tokens=estimate}function selectCompactionCollection(result,minimumRowsByPath){return readOutputBudgetCollections(result).filter(collection=>{const length=Array.isArray(collection.value)?collection.value.length:Object.keys(collection.value).length;return length>Math.max(1,minimumRowsByPath.get(collection.path)??0)}).map(collection=>({collection,length:Array.isArray(collection.value)?collection.value.length:Object.keys(collection.value).length})).sort((left,right)=>right.length-left.length||left.collection.path.localeCompare(right.collection.path))[0]?.collection}function compactRowsToBudget(result,receipt,budget,minimumRowsByPath,format,finalize){for(let iteration=0;iteration<MAX_COMPACTION_ITERATIONS;iteration+=1){finalize?.(result);updateReadOutputReceiptEstimate(result,receipt,format);if(receipt.estimated_tokens<=budget)return;const candidate=selectCompactionCollection(result,minimumRowsByPath);if(!candidate)return;const minimumRows=Math.max(1,minimumRowsByPath.get(candidate.path)??0);const values=Array.isArray(candidate.value)?[...candidate.value]:Object.entries(candidate.value);const retainPrefix=length=>{if(Array.isArray(candidate.value)){candidate.value.length=length;for(let index=0;index<length;index+=1)candidate.value[index]=values[index]}else{for(const key of Object.keys(candidate.value))delete candidate.value[key];Object.defineProperties(candidate.value,Object.getOwnPropertyDescriptors(Object.fromEntries(values.slice(0,length))))}if(typeof result.count==="number")result.count=countReadOutputRows(result);if(candidate.path==="items")result.applied_limit=length;finalize?.(result);updateReadOutputReceiptEstimate(result,receipt,format)};receipt.rows_compacted=true;receipt.compacted_row_paths=[...new Set([...receipt.compacted_row_paths??[],candidate.path])].sort((left,right)=>left.localeCompare(right));result.has_more=true;result.truncated=true;let low=minimumRows;let high=values.length-1;let retained=minimumRows;while(low<=high){const middle=Math.floor((low+high)/2);retainPrefix(middle);if(receipt.estimated_tokens<=budget){retained=middle;low=middle+1}else{high=middle-1}}retainPrefix(retained)}}function compactReadOutputToBudget(result,receipt,budget,minimumRowsByPath=new Map,format,finalize){const stringCompactionState={compacted:false};const compacted=compactStrings(result,stringCompactionState);preserveReadOutputRowContract(result,compacted);receipt.strings_compacted=stringCompactionState.compacted;compacted.read_output=receipt;compactRowsToBudget(compacted,receipt,budget,minimumRowsByPath,format,finalize);updateReadOutputReceiptEstimate(compacted,receipt,format);return compacted}export{compactReadOutputToBudget,estimateReadOutputTokens,preserveReadOutputRowContract,projectReadOutputItemToBrief,resolveReadOutputRecoveryBudget,updateReadOutputReceiptEstimate};
|
|
2
2
|
//# sourceMappingURL=read-output-budget.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(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]="43055f93-73df-541f-b179-3cc67e4a1a03")}catch(e2){}})();import{resolvePmHistoryOperation}from"./cli-contracts/command-aliases.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{compactReadOutputToBudget,estimateReadOutputTokens,projectReadOutputItemToBrief,resolveReadOutputRecoveryBudget,updateReadOutputReceiptEstimate}from"./read-output-budget.js";import{resolveReadOutputRecoveryBudget as resolveReadOutputRecoveryBudget2}from"./read-output-budget.js";import{resolvePmCommandOutputBudget}from"./cli-contracts/agent-output-contracts.js";import{boundReadOutputRows,countReadOutputRows,mapReadOutputRows,readOutputBudgetCollections,readOutputContinuationRowCollections,readOutputRowPaths}from"./read-output-rows.js";import{applyReadOutputContinuation,decodeReadOutputContinuationCursor,encodeReadOutputContinuationCursor,prioritizeAssuranceAssertions,readOutputCollectionFingerprint}from"./read-output/continuation.js";import{decodeReadOutputContinuationCursor as decodeReadOutputContinuationCursor2,encodeReadOutputContinuationCursor as encodeReadOutputContinuationCursor2,PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES,readOutputCollectionFingerprint as readOutputCollectionFingerprint2}from"./read-output/continuation.js";import{applyReadOutputSessionReferences,attachReadOutputSessionReceipt,parseReadOutputSession,readOutputSessionRemainingTokens}from"./read-output-session.js";import{decodeQueryCursorEnvelope,encodeQueryCursor}from"./pagination.js";const PM_READ_OUTPUT_DIMENSIONS=["include","amount","cost","encoding"];const PM_READ_OUTPUT_SURFACES=["list","context","search","get","next","health","deps","graph","history","activity","validate","events","contracts","comments","notes","files","docs","stats","aggregate","duplicates","package-catalog","package-manage","comments-audit","assurance"];const READ_OUTPUT_PRECEDENCE=["canonical","legacy","intent","default"];const CANONICAL_OPTIONS={include:"--output-include",amount:"--output-limit",cost:"--output-budget",encoding:"--output-format"};const READ_OUTPUT_INVOCATION_PROVENANCE=Symbol.for("pm.readOutputInvocationProvenance");const PM_READ_OUTPUT_OPTION_FLAGS=Object.freeze(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>CANONICAL_OPTIONS[dimension]));const PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS=Object.freeze(["--output-session","--output-cursor","--output-row-contract"]);const LEGACY_FLAGS_BY_COMMAND={list:{include:["--brief","--compact","--fields","--full"],amount:["--after","--limit","--no-truncate"],cost:["--token-budget"],encoding:["--format","--stream"]},context:{include:["--fields","--section"],amount:["--after","--depth","--limit"],cost:["--token-budget"],encoding:["--format"]},search:{include:["--compact","--fields","--full"],amount:["--after","--limit"],cost:["--token-budget"],encoding:["--format"]},get:{include:["--fields","--full"],amount:["--depth"],cost:["--token-budget"],encoding:["--format"]},next:{amount:["--blocked-limit","--limit"],cost:["--token-budget"],encoding:["--format"]},health:{include:["--brief","--check-only","--full","--summary"]},deps:{include:["--collapse","--full","--summary"],amount:["--edge-limit","--max-depth","--node-limit"],cost:["--token-budget"],encoding:["--format"]},graph:{include:["--full","--summary"],amount:["--after","--limit","--max-depth","--max-paths"]},history:{include:["--compact","--full"],amount:["--limit"],encoding:["--format"]},activity:{include:["--compact","--full"],amount:["--limit","--unbounded"],encoding:["--stream"]},validate:{include:["--counts","--full"]},events:{include:["--full"],amount:["--limit"],encoding:["--follow"]},contracts:{include:["--full","--summary"]},comments:{amount:["--limit"]},notes:{amount:["--limit"]},files:{amount:["--limit","--no-truncate","--offset"]},docs:{},stats:{},aggregate:{},duplicates:{amount:["--limit"]},"package-catalog":{},"package-manage":{},"comments-audit":{},assurance:{}};const VALUE_BEARING_INCLUDE_ALIASES=new Set(["--collapse","--fields","--section"]);const BEHAVIOR_PRESERVING_MIGRATION_HINTS=Object.freeze({"--after":"--after retains cursor-position semantics; use --output-limit <n> separately to bound returned rows.","--check-only":"--check-only retains health side-effect semantics; --output-include does not suppress vector refresh.","--collapse":"--collapse retains dependency grouping semantics; --output-include does not replace it.","--depth":"--depth retains traversal or detail-depth semantics; --output-limit does not replace it.","--follow":"--follow retains event-tail semantics; --output-format does not enable following.","--max-depth":"--max-depth retains graph traversal-depth semantics; --output-limit does not replace it.","--max-paths":"--max-paths retains graph path-search semantics; use --output-limit separately to bound returned rows.","--no-truncate":"--no-truncate is a compatibility alias; prefer --output-limit unbounded.","--offset":"--offset retains positional pagination semantics; use --output-limit separately to bound returned rows.","--stream":"--stream retains command streaming semantics; --output-format selects only static result encoding.","--unbounded":"--unbounded is a compatibility alias; prefer --output-limit unbounded."});function flagSelector(flag){return flag.slice(2).replaceAll("-","_")}function migrationHint(flag,dimension){const behaviorHint=BEHAVIOR_PRESERVING_MIGRATION_HINTS[flag];if(behaviorHint!==void 0)return behaviorHint;const suffix=dimension==="include"?VALUE_BEARING_INCLUDE_ALIASES.has(flag)?"<csv>":flagSelector(flag):dimension==="amount"?"<n>":dimension==="cost"?"<tokens>":"<toon|json>";return`${flag} is a compatibility alias; prefer ${CANONICAL_OPTIONS[dimension]} ${suffix}.`}function buildSurfaceContract(command){const legacy=LEGACY_FLAGS_BY_COMMAND[command];const dimensions=Object.freeze(Object.fromEntries(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>[dimension,Object.freeze({dimension,canonical_option:CANONICAL_OPTIONS[dimension],applicable:true,inapplicable_reason:null,legacy_aliases:Object.freeze((legacy[dimension]??[]).map(flag=>Object.freeze({flag,semantics:BEHAVIOR_PRESERVING_MIGRATION_HINTS[flag]===void 0?"replacement":"behavior_preserving",migration_hint:migrationHint(flag,dimension),visibility:"hidden_alias"})))})])));return Object.freeze({command,dimensions,precedence:READ_OUTPUT_PRECEDENCE,budget_retention_policy:command==="assurance"?"verdict_priority":"ordered_prefix",projection_modes:Object.freeze([...readOutputIncludeModeOptions(command).keys()])})}const PM_READ_OUTPUT_SURFACE_CONTRACTS=Object.freeze(PM_READ_OUTPUT_SURFACES.map(buildSurfaceContract));const SURFACE_CONTRACT_BY_COMMAND=new Map(PM_READ_OUTPUT_SURFACE_CONTRACTS.map(contract=>[contract.command,contract]));function resolveReadOutputSurface(command,options={}){const normalizedCommand=resolvePmHistoryOperation(command.trim().toLowerCase());const packageMode=normalizedCommand==="package catalog"||normalizedCommand==="packages catalog"||normalizedCommand==="package-catalog"||(normalizedCommand==="package"||normalizedCommand==="packages"||normalizedCommand==="extension")&&(options.catalog===true||options.target==="catalog"||options.action==="catalog");const root=packageMode?"package-catalog":normalizedCommand==="package manage"||normalizedCommand==="package-manage"?"package-manage":normalizedCommand.split(" ")[0];const normalized=root.startsWith("list-")?"list":root==="ctx"?"context":root;return PM_READ_OUTPUT_SURFACES.includes(normalized)?normalized:void 0}const CANONICAL_OPTION_KEYS=["outputInclude","output_include","outputLimit","output_limit","outputBudget","output_budget","outputFormat","output_format","outputSession","output_session","outputCursor","output_cursor","outputRowContract","output_row_contract"];const HYBRID_READ_MUTATION_KEYS={comments:["add","body","stdin","file","edit","delete"],notes:["add","addJson","stdin","file","edit","delete"],files:["add","addGlob","remove","migrate","apply","note"],docs:["add","addGlob","remove","migrate","note"],"package-catalog":["activate","adopt","adoptAll","deactivate","doctor","init","install","manage","migrate","reload","scaffold","uninstall"]};function hasCanonicalReadOutputOptions(options){return CANONICAL_OPTION_KEYS.some(key=>options[key]!==void 0)}const READ_OUTPUT_VALUE_VALIDATORS=[{keys:["outputInclude","output_include"],valid:value=>stringList(value)!==void 0,message:"--output-include requires at least one comma-separated field or section."},{keys:["outputLimit","output_limit"],valid:value=>value==="unbounded"||positiveInteger(value)!==void 0,message:"--output-limit must be a positive integer or unbounded."},{keys:["outputBudget","output_budget"],valid:value=>value==="unbounded"||positiveInteger(value)!==void 0,message:"--output-budget must be a positive integer or unbounded."},{keys:["outputFormat","output_format"],valid:value=>value==="toon"||value==="json",message:"--output-format must be toon or json."},{keys:["outputSession","output_session"],valid:value=>{parseReadOutputSession(value);return true},message:"--output-session must be a valid session-state object."},{keys:["outputCursor","output_cursor"],valid:value=>typeof value==="string"&&value.trim().length>0,message:"--output-cursor requires a non-empty continuation cursor."}];function validateReadOutputOptions(command,options){if(!hasCanonicalReadOutputOptions(options))return;const normalizedCommand=resolveReadOutputSurface(command,options);if(!normalizedCommand){throw new PmCliError(`Universal output controls apply only to read commands; ${command||"this command"} is not a read surface.`,EXIT_CODE.USAGE)}if((HYBRID_READ_MUTATION_KEYS[normalizedCommand]??[]).some(key=>options[key]!==void 0&&options[key]!==false)){throw new PmCliError(`Universal output controls cannot be combined with a ${normalizedCommand} mutation.`,EXIT_CODE.USAGE)}for(const validator of READ_OUTPUT_VALUE_VALIDATORS){const value=validator.keys.map(key=>options[key]).find(entry=>entry!==void 0);if(value!==void 0&&!validator.valid(value)){throw new PmCliError(validator.message,EXIT_CODE.USAGE)}}}function readOutputIncludeModeOptions(command){const surface=resolveReadOutputSurface(command);if(!surface)return new Map;return new Map((LEGACY_FLAGS_BY_COMMAND[surface].include??[]).filter(flag=>!VALUE_BEARING_INCLUDE_ALIASES.has(flag)&&BEHAVIOR_PRESERVING_MIGRATION_HINTS[flag]===void 0).map(flag=>[flagSelector(flag),optionKey(flag)]))}function applyReadOutputIncludeModes(command,includeValue,commandOptions){const requested=stringList(includeValue)??[];const modeOptions=readOutputIncludeModeOptions(command);const selectors=[];const modes=[];const optionsWithProvenance=commandOptions;const existingProvenance=optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE];const canonicalModes=new Set(existingProvenance?.canonical_include_modes??[]);const explicitLegacyAliases=new Set(existingProvenance?.explicit_legacy_aliases??[]);for(const token of requested){const option=modeOptions.get(token);if(option===void 0){selectors.push(token);continue}const legacyFlag=`--${token.replaceAll("_","-")}`;if(isRequestedOption(readOption(commandOptions,legacyFlag))){explicitLegacyAliases.add(legacyFlag)}commandOptions[option]=true;modes.push(token);canonicalModes.add(token)}const forwardedGetFieldSelectors=resolveReadOutputSurface(command)==="get"?selectors.filter(selector=>selector!=="item"):[];const forwardedGetFields=forwardedGetFieldSelectors.length>0;if(forwardedGetFields){commandOptions.fields=[...new Set([...stringList(commandOptions.fields)??[],...forwardedGetFieldSelectors])].join(",");canonicalModes.add("fields")}if(modes.length>0||forwardedGetFields){optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE]={canonical_include_modes:[...canonicalModes],explicit_legacy_aliases:[...explicitLegacyAliases],...existingProvenance?.cli_invocation_observed===true?{cli_invocation_observed:true}:{}}}return{selectors,modes}}function normalizeReadOutputIncludeModeOptions(command,options){const include=options.outputInclude??options.output_include;if(include===void 0)return;const{selectors,modes}=applyReadOutputIncludeModes(command,include,options);if(modes.length===0)return;const residual=selectors.length>0?selectors.join(","):void 0;options.outputInclude=residual;if(Object.hasOwn(options,"output_include")){options.output_include=residual}}function optionKey(flag){return flag.slice(2).replace(/-([a-z])/gu,(_,character)=>character.toUpperCase())}function readOption(options,flag){const key=optionKey(flag);if(Object.hasOwn(options,key))return options[key];const snakeKey=flag.slice(2).replaceAll("-","_");if(Object.hasOwn(options,snakeKey))return options[snakeKey];if(flag==="--no-truncate"&&options.truncate===false)return true;return void 0}function isRequestedOption(value){return value!==void 0&&value!==false&&value!==null}function stringList(value){const values=Array.isArray(value)?value:[value];const normalized=values.flatMap(entry=>typeof entry==="string"?entry.split(","):[]).map(entry=>entry.trim()).filter(Boolean);return normalized.length>0?[...new Set(normalized)]:void 0}function positiveInteger(value){const parsed=typeof value==="number"?value:typeof value==="string"&&/^\d+$/u.test(value.trim())?Number(value):Number.NaN;return Number.isSafeInteger(parsed)&&parsed>0?parsed:void 0}function resolveLegacyDimension(contract,options,usable,ignore){for(const alias of contract.legacy_aliases){if(ignore(alias.flag))continue;const value=readOption(options,alias.flag);const candidate={value,flag:alias.flag};if(isRequestedOption(value)&&usable(candidate))return candidate}return void 0}function resolveIncludeValue(canonical,legacy){const canonicalList=stringList(canonical);if(canonicalList)return{source:"canonical",value:canonicalList};if(!legacy)return void 0;return{source:"legacy",value:stringList(legacy.value)??[flagSelector(legacy.flag)]}}function resolveAmountValue(canonical,legacy){if(canonical==="unbounded"){return{source:"canonical",value:"unbounded"}}const canonicalLimit=positiveInteger(canonical);if(canonicalLimit!==void 0){return{source:"canonical",value:canonicalLimit}}if(!legacy)return void 0;if(legacy.flag==="--no-truncate"||legacy.flag==="--unbounded"){return{source:"legacy",value:"unbounded"}}const legacyLimit=positiveInteger(legacy.value);return legacyLimit===void 0?void 0:{source:"legacy",value:legacyLimit}}function resolveCostValue(canonical,legacy){if(canonical==="unbounded"){return{source:"canonical",value:"unbounded"}}const canonicalBudget=positiveInteger(canonical);if(canonicalBudget!==void 0){return{source:"canonical",value:canonicalBudget}}if(!legacy)return void 0;const legacyBudget=positiveInteger(legacy.value);return legacyBudget===void 0?void 0:{source:"legacy",value:legacyBudget}}function resolveEncodingValue(canonical,legacy){if(canonical==="json"||canonical==="toon"){return{source:"canonical",value:canonical}}if(!legacy)return void 0;if(legacy.flag==="--stream"||legacy.flag==="--follow"){return{source:"legacy",value:"stream"}}return legacy.value==="json"||legacy.value==="toon"?{source:"legacy",value:legacy.value}:void 0}function shouldIgnoreReadOutputLegacyAlias(provenance,dimension,flag){if(!provenance)return false;const explicitLegacyAliases=new Set(provenance.explicit_legacy_aliases);if(provenance.cli_invocation_observed===true){return!explicitLegacyAliases.has(flag)}const forwardedIncludeAliases=new Set(provenance.canonical_include_modes.map(mode=>`--${mode.replaceAll("_","-")}`));return dimension==="include"&&forwardedIncludeAliases.has(flag)&&!explicitLegacyAliases.has(flag)}function hasCompleteReadOutputIntent(command,legacyByDimension,provenance){const root=command.trim().toLowerCase().replaceAll(/\s+/gu," ").split(" ")[0];return root==="list-all"||legacyByDimension.amount?.flag==="--no-truncate"||legacyByDimension.include?.flag==="--full"||provenance?.canonical_include_modes.includes("full")===true}function canonicalReadOutputOptionsUsed(resolvedByDimension,provenance){return PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>resolvedByDimension[dimension]?.source==="canonical"||dimension==="include"&&(provenance?.canonical_include_modes.length??0)>0?[CANONICAL_OPTIONS[dimension]]:[])}function resolveReadOutputDimensions(command,options){const normalizedCommand=resolveReadOutputSurface(command,options);if(!normalizedCommand)return void 0;const contract=SURFACE_CONTRACT_BY_COMMAND.get(normalizedCommand);const invocationProvenance=options[READ_OUTPUT_INVOCATION_PROVENANCE];const legacyResolvers={include:candidate=>resolveIncludeValue(void 0,candidate),amount:candidate=>resolveAmountValue(void 0,candidate),cost:candidate=>resolveCostValue(void 0,candidate),encoding:candidate=>resolveEncodingValue(void 0,candidate)};const legacyByDimension=Object.fromEntries(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>[dimension,resolveLegacyDimension(contract.dimensions[dimension],options,candidate=>legacyResolvers[dimension](candidate)!==void 0,flag=>shouldIgnoreReadOutputLegacyAlias(invocationProvenance,dimension,flag))]));const legacyAliasesUsed=PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>{const resolved=legacyByDimension[dimension];return resolved?[resolved.flag]:[]});const migrationHints=PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>{const resolved=legacyByDimension[dimension];if(!resolved)return[];const alias=contract.dimensions[dimension].legacy_aliases.find(entry=>entry.flag===resolved.flag);return[alias.migration_hint]});const encoding=resolveEncodingValue(options.outputFormat??options.output_format,legacyByDimension.encoding);const include=resolveIncludeValue(options.outputInclude??options.output_include,legacyByDimension.include);const amount=resolveAmountValue(options.outputLimit??options.output_limit,legacyByDimension.amount);const explicitCost=resolveCostValue(options.outputBudget??options.output_budget,legacyByDimension.cost);const completeResultIntent=hasCompleteReadOutputIntent(command,legacyByDimension,invocationProvenance);const budget=resolvePmCommandOutputBudget(command,{generateFallback:true});const resolvedOutputFormat=encoding?.value==="json"||options.resolvedOutputFormat==="json"?"json":"toon";const cost=explicitCost??(completeResultIntent?{source:"intent",value:"unbounded"}:{source:"default",value:budget.default_max_estimated_tokens_by_format[resolvedOutputFormat]});const resolvedByDimension={include,amount,cost,encoding};return{command:normalizedCommand,include,amount,cost,encoding,canonical_options_used:canonicalReadOutputOptionsUsed(resolvedByDimension,invocationProvenance),legacy_aliases_used:legacyAliasesUsed,migration_hints:migrationHints,precedence:READ_OUTPUT_PRECEDENCE}}function isRecord(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)}const ENVELOPE_KEYS=new Set(["applied_bound","applied_limit","completeness","continuation_kind","continuation_path","continuation_contract","count","filters","has_more","next_cursor","now","omission_receipt","projection","budget_retention_policy","row_contract","sorting","total","truncated"]);const GET_STABLE_DERIVED_ITEM_SELECTORS=["collection_counts","notes_count","tests_count"];function projectRecordFields(value,selectors){const selected=new Set(selectors.map(selector=>selector.split(".")[0]));return Object.fromEntries(Object.entries(value).filter(([key])=>selected.has(key)))}function getProjectionVocabulary(result){const item=isRecord(result.item)?result.item:{};const itemFields=[...new Set([...Object.keys(item),...GET_STABLE_DERIVED_ITEM_SELECTORS.filter(key=>Object.hasOwn(item,key))])].sort((left,right)=>left.localeCompare(right));const sections=Object.keys(result).filter(key=>key!=="item"&&key!=="read_output"&&!ENVELOPE_KEYS.has(key)).sort((left,right)=>left.localeCompare(right));return{item,itemFields,sections,valid:[...itemFields,"item",...itemFields.map(field=>`item.${field}`),...sections]}}function applyGetIncludeProjection(result,selectors){const vocabulary=getProjectionVocabulary(result);const unknown=selectors.filter(selector=>!vocabulary.valid.includes(selector));if(unknown.length>0){throw new PmCliError(`Unknown --output-include selector(s) for get: ${unknown.join(", ")}. Valid selectors: ${vocabulary.valid.join(", ")}.`,EXIT_CODE.USAGE)}const fullItem=selectors.includes("item");const itemSelectors=selectors.flatMap(selector=>selector.startsWith("item.")?[selector.slice("item.".length)]:vocabulary.itemFields.includes(selector)?[selector]:[]).filter((selector,index,values)=>values.indexOf(selector)===index);if(fullItem&&itemSelectors.length>0){throw new PmCliError("--output-include cannot mix a full item with projected item fields; use item or item.<field>, not both.",EXIT_CODE.USAGE)}const selectedSections=new Set(selectors.filter(selector=>vocabulary.sections.includes(selector)));const projected=Object.fromEntries(Object.entries(result).filter(([key])=>ENVELOPE_KEYS.has(key)||selectedSections.has(key)));if(fullItem){projected.item=vocabulary.item}else if(itemSelectors.length>0){projected.item=projectRecordFields(vocabulary.item,itemSelectors)}const omittedFieldGroups=[...fullItem?[]:itemSelectors.length>0?vocabulary.itemFields.filter(field=>!itemSelectors.includes(field)).map(field=>({name:`item.${field}`,restore_with:`--output-include item.${field}`})):[{name:"item",restore_with:"--output-include item"}],...vocabulary.sections.filter(section=>!selectedSections.has(section)).map(section=>({name:section,restore_with:`--output-include ${section}`}))];const inheritedOmittedFieldGroups=isRecord(projected.omission_receipt)&&Array.isArray(projected.omission_receipt.omitted_field_groups)?projected.omission_receipt.omitted_field_groups:[];const combinedOmittedFieldGroups=[...inheritedOmittedFieldGroups,...omittedFieldGroups];projected.omission_receipt={has_omissions:combinedOmittedFieldGroups.length>0,omitted_field_group_count:combinedOmittedFieldGroups.length,omitted_field_groups:combinedOmittedFieldGroups};return projected}function countPopulatedRows(result){let populated=0;mapReadOutputRows({...result},entry=>{if(isRecord(entry)&&Object.keys(entry).length>0)populated+=1;return entry});return populated}function rejectEmptyIncludeProjection(command,original,shaped,selectors){if(countPopulatedRows(original)===0||countPopulatedRows(shaped)>0){return}const modes=[...readOutputIncludeModeOptions(command).keys()];const domain=modes.length>0?` Declared ${command} projection modes: ${modes.join(", ")}.`:` The ${command} surface declares no projection modes; name row fields instead.`;throw new PmCliError(`Unknown --output-include selector(s) for ${command}: ${selectors.join(", ")}. No selector matched any returned row field.${domain}`,EXIT_CODE.USAGE)}function applyIncludeProjection(command,result,selectors){if(command==="get"){return applyGetIncludeProjection(result,selectors)}const rows=readOutputRowPaths(result);const qualifiedRowSelectors=selectors.flatMap(selector=>rows.flatMap(rowPath=>selector.startsWith(`${rowPath}.`)?[selector.slice(rowPath.length+1)]:[]));const selectedRoot=selectors.some(selector=>Object.hasOwn(result,selector.split(".")[0])&&!rows.some(rowPath=>selector.startsWith(`${rowPath}.`)));if(rows.length>0&&(!selectedRoot||qualifiedRowSelectors.length>0)){const projected={...result};const rowSelectors=qualifiedRowSelectors.length>0?qualifiedRowSelectors:selectors;const shaped=mapReadOutputRows(projected,entry=>isRecord(entry)?projectRecordFields(entry,rowSelectors):entry);rejectEmptyIncludeProjection(command,result,shaped,rowSelectors);return shaped}return Object.fromEntries(Object.entries(result).filter(([key])=>selectors.some(selector=>selector.split(".")[0]===key)||ENVELOPE_KEYS.has(key)))}function applyAmountBound(result,amount){if(amount==="unbounded")return result;const{result:bounded,truncated}=boundReadOutputRows(result,amount);if(!truncated)return bounded;bounded.has_more=true;bounded.truncated=true;if(typeof bounded.count==="number"){bounded.count=countReadOutputRows(bounded)}bounded.applied_bound={kind:"output_limit",source:"explicit",value:amount};return bounded}function requestedDimensions(resolved){return PM_READ_OUTPUT_DIMENSIONS.filter(dimension=>resolved[dimension]!==void 0&&resolved[dimension]?.source!=="default"||resolved.canonical_options_used.includes(CANONICAL_OPTIONS[dimension]))}function readOutputMeasurementFormat(options){const format=options.resolvedOutputFormat??options.outputFormat??options.output_format??options.format;return format==="json"||format==="toon"?format:void 0}function attachReadOutputSessionContracts(result,state,receipt,format){let withSession=attachReadOutputSessionReceipt(result,state,format);for(let iteration=0;iteration<8;iteration+=1){const previousReadEstimate=receipt.estimated_tokens;const previousSessionEstimate=withSession.read_session.spent_this_call_tokens;updateReadOutputReceiptEstimate(withSession,receipt,format);withSession=attachReadOutputSessionReceipt(withSession,state,format);const sessionEstimate=withSession.read_session.spent_this_call_tokens;if(receipt.estimated_tokens===previousReadEstimate&&sessionEstimate===previousSessionEstimate){return withSession}}return withSession}function stabilizeReadOutputReceiptEstimates(result,options){if(!isRecord(result.read_output))return result;const format=readOutputMeasurementFormat(options);const receipt=result.read_output;const session=parseReadOutputSession(options.outputSession??options.output_session);if(session===void 0){updateReadOutputReceiptEstimate(result,receipt,format);return result}return attachReadOutputSessionContracts(result,session,receipt,format)}function attachValidateDiagnosticRowContract(command,result){if(command!=="validate")return result;const projection=isRecord(result.projection)?result.projection:void 0;const declaredFieldGroups=Array.isArray(projection?.declared_field_groups)?projection.declared_field_groups:[];if(!declaredFieldGroups.some(group=>isRecord(group)&&group.name==="diagnostic_rows")){return result}const diagnosticCollectionPaths=[...new Set(readOutputBudgetCollections(result).map(({path})=>path).filter(path=>/^checks\.\d+\.details\./u.test(path)))];const diagnosticRowKeys=diagnosticCollectionPaths.filter(path=>!diagnosticCollectionPaths.some(candidate=>candidate!==path&&path.startsWith(`${candidate}.`)));if(diagnosticRowKeys.length===0)return result;const existingContract=isRecord(result.row_contract)?result.row_contract:{};const existingRowKeys=Array.isArray(existingContract.row_keys)?existingContract.row_keys.filter(entry=>typeof entry==="string"):[];const existingContinuationRowKeys=Array.isArray(existingContract.continuation_row_keys)?existingContract.continuation_row_keys.filter(entry=>typeof entry==="string"):[];const rowKeys=existingRowKeys.length>0?existingRowKeys:diagnosticRowKeys;const continuationRowKeys=[...new Set(diagnosticRowKeys)];return JSON.stringify(rowKeys)===JSON.stringify(existingRowKeys)&&JSON.stringify(continuationRowKeys)===JSON.stringify(existingContinuationRowKeys)?result:{...result,row_contract:{...existingContract,row_keys:rowKeys,continuation_row_keys:continuationRowKeys,jq_selector:typeof existingContract.jq_selector==="string"?existingContract.jq_selector:".checks[].details"}}}function projectReadOutputRows(result,resolved,session,cursor){let projected={...result};if(resolved.include?.source==="canonical"){projected=applyIncludeProjection(resolved.command,projected,resolved.include.value)}if(resolved.command==="assurance"){projected=prioritizeAssuranceAssertions(projected)}projected=applyReadOutputContinuation(projected,resolved.command,cursor);if(resolved.amount?.source==="canonical"){projected=applyAmountBound(projected,resolved.amount.value)}return session===void 0?projected:applyReadOutputSessionReferences(projected,session)}function resolveBindingReadOutputBudget(resolved,session){const budgets=[...resolved.cost!==void 0&&resolved.cost.value!=="unbounded"&&(resolved.cost.source==="canonical"||resolved.cost.source==="default")?[{source:resolved.cost.source,tokens:resolved.cost.value}]:[],...session===void 0?[]:[{source:"session",tokens:readOutputSessionRemainingTokens(session)}]];return budgets.sort((left,right)=>left.tokens-right.tokens)[0]}function canonicalReadOutputReceiptFields(resolved){const canonicalOptions=resolved.canonical_options_used;return canonicalOptions&&canonicalOptions.length>0?{canonical_options_used:canonicalOptions}:{}}function omitReadOutputForBudget(resolved,requested,session,bindingBudget,omittedResultEstimatedTokens,format){const minimalReceipt={contract_version:1,command:resolved.command,requested_dimensions:requested,...bindingBudget.source==="default"?{budget_source:bindingBudget.source,budget_tokens:bindingBudget.tokens}:{},precedence:resolved.precedence,...canonicalReadOutputReceiptFields(resolved),legacy_aliases_used:[],migration_hints:[],estimated_tokens:0,within_budget:false,strings_compacted:false,rows_compacted:false,result_omitted:true,...session===void 0?{omitted_result_estimated_tokens:omittedResultEstimatedTokens}:{}};const omitted={output_budget_exceeded:{omitted_result:true,reason:"requested_budget_infeasible",restore_with:"Unbounded",recovery:{outputBudget:"unbounded"}},read_output:minimalReceipt};const boundedOmission=session===void 0?omitted:attachReadOutputSessionContracts(omitted,session,minimalReceipt,format);if(session===void 0){updateReadOutputReceiptEstimate(boundedOmission,minimalReceipt,format)}if(session!==void 0&&minimalReceipt.estimated_tokens>bindingBudget.tokens){throw new PmCliError("The remaining output-session budget cannot fit its mandatory receipts; start a new session with a larger token_budget.",EXIT_CODE.USAGE)}return boundedOmission}function canReturnReadOutputUnchanged(resolved,session,result,format){if(session!==void 0)return false;const canonicalRequestedCount=resolved.canonical_options_used.length;if(resolved.cost?.value==="unbounded"){return canonicalRequestedCount===(resolved.cost.source==="canonical"?1:0)}if(resolved.cost?.source==="legacy"&&canonicalRequestedCount===0){return true}return canonicalRequestedCount===0&&(resolved.cost===void 0||estimateReadOutputTokens(result,format)<=resolved.cost.value)}function attachReadOutputTruncationDisclosure(projected,resolved,receipt,bindingBudget,continuationCursorRebased,measuredResultTokens,collectionsBeforeBudget){if(!receipt.rows_compacted)return;const overridden=resolved.amount?.value==="unbounded"?["amount"]:[];const afterByPath=new Map(readOutputContinuationRowCollections(projected).map(collection=>[collection.path,Array.isArray(collection.value)?collection.value.length:Object.keys(collection.value).length]));const continuations=[...collectionsBeforeBudget.entries()].flatMap(([path,before])=>{const retainedRows=afterByPath.get(path);if(retainedRows>=before.rows)return[];const offset=before.baseOffset+retainedRows;return[{path,cursor:encodeReadOutputContinuationCursor({command:resolved.command,path,offset,total_rows:before.totalRows,fingerprint:before.fingerprint}),retained_rows:retainedRows,remaining_rows:before.totalRows-offset,total_rows:before.totalRows}]});const primary=continuations[0];const continuationHint=primary?"; page --output-cursor":"";const budgetHint=bindingBudget.source==="session"?`Truncated by the remaining ${bindingBudget.tokens}-token session budget; start a new output session with a larger token_budget${continuationHint}.`:`${bindingBudget.tokens}-token: raise --output-budget${continuationHint}`;receipt.migration_hints=[budgetHint,...resolved.migration_hints];const recoveryBudget=resolveReadOutputRecoveryBudget({effective_budget_tokens:bindingBudget.tokens,measured_result_tokens:measuredResultTokens});if(primary&&typeof projected.next_cursor!=="string"){projected.next_cursor=primary.cursor}projected.continuation_kind=continuationCursorRebased?"producer_cursor":primary?"output_cursor":"none";projected.output_budget_truncation={reason:"output_budget_reached",budget_source:bindingBudget.source,budget_tokens:bindingBudget.tokens,overridden_dimensions:overridden,compacted_row_paths:receipt.compacted_row_paths,continuation_cursor_rebased:continuationCursorRebased,continuation_available:continuations.length>0,recovery_budget_multiplier:primary?1:recoveryBudget.recovery_budget_multiplier,continuations,restore_with:primary?"recovery":`Retry with --output-budget ${recoveryBudget.output_budget} because no declared row collection can be continued.`,recovery:primary?{cursor:primary.cursor,cli:"--output-cursor",sdk:"outputCursor",mcp:"outputCursor"}:{cli:`--output-budget ${recoveryBudget.output_budget}`,sdk:{outputBudget:recoveryBudget.output_budget},mcp:{outputBudget:recoveryBudget.output_budget}}}}function rebaseBudgetCompactedCursor(projected,originalItemCount,cursorSource,cursorContinuesExistingPage){if(typeof cursorSource!=="string"||!Array.isArray(projected.items)){return false}const retainedCount=projected.items.length;if(retainedCount===0||retainedCount>=originalItemCount){return false}let cursor;try{cursor=decodeQueryCursorEnvelope(cursorSource)}catch{return false}const sourceIndex=cursor.after_index;if(sourceIndex===void 0)return false;const last=projected.items.at(-1);if(Object.prototype.toString.call(last)!=="[object Object]"){return false}const lastId=Reflect.get(last,"id");if(typeof lastId!=="string"||lastId.length===0)return false;const afterIndex=cursorContinuesExistingPage?sourceIndex-(originalItemCount-retainedCount):sourceIndex+retainedCount;if(afterIndex<0)return false;projected.next_cursor=encodeQueryCursor(cursor.fingerprint,lastId,afterIndex,cursor.snapshot);if(typeof projected.applied_limit==="number"){projected.applied_limit=retainedCount}return true}function captureReadOutputContinuationState(projected,command,cursor,options){const collectionsBeforeBudget=new Map(readOutputContinuationRowCollections(projected).map(collection=>{const rows=Array.isArray(collection.value)?collection.value.length:Object.keys(collection.value).length;const continued=cursor?.path===collection.path;return[collection.path,{rows,totalRows:continued?cursor.total_rows:rows,baseOffset:continued?cursor.offset:0,fingerprint:continued?cursor.fingerprint:readOutputCollectionFingerprint(collection.path,collection.value,command)}]}));const cursorContinuesExistingPage=typeof projected.next_cursor==="string";return{collectionsBeforeBudget,originalItemCount:Array.isArray(projected.items)?projected.items.length:0,cursorContinuesExistingPage,cursorSource:cursorContinuesExistingPage?projected.next_cursor:options.after}}function compactReadOutputProjection(projected,resolved,receipt,bindingBudget,session,continuationState,measuredResultTokens,format){const assuranceMinimumRows=resolved.command==="assurance"&&Array.isArray(projected.assertions)?projected.assertions.filter(row=>isRecord(row)&&row.verdict!=="pass").length:0;let targetBudget=bindingBudget.tokens;let compacted=projected;for(let iteration=0;iteration<8;iteration+=1){compacted=compactReadOutputToBudget(projected,receipt,targetBudget,assuranceMinimumRows>0?new Map([["assertions",assuranceMinimumRows]]):new Map,format);const continuationCursorRebased=rebaseBudgetCompactedCursor(compacted,continuationState.originalItemCount,continuationState.cursorSource,continuationState.cursorContinuesExistingPage);attachReadOutputTruncationDisclosure(compacted,resolved,receipt,bindingBudget,continuationCursorRebased,measuredResultTokens,continuationState.collectionsBeforeBudget);if(session!==void 0){compacted=attachReadOutputSessionContracts(compacted,session,receipt,format)}updateReadOutputReceiptEstimate(compacted,receipt,format);const overrun=receipt.estimated_tokens-bindingBudget.tokens;if(overrun<=0||targetBudget<=0)return compacted;targetBudget=Math.max(0,targetBudget-overrun)}return compacted}function applyReadOutputDimensions(command,options,result){const resolved=resolveReadOutputDimensions(command,options);if(!resolved)return result;const format=readOutputMeasurementFormat(options);const session=parseReadOutputSession(options.outputSession??options.output_session);const rawCursor=options.outputCursor??options.output_cursor;const cursor=typeof rawCursor==="string"?decodeReadOutputContinuationCursor(rawCursor):void 0;const requested=requestedDimensions(resolved);if(cursor===void 0&&canReturnReadOutputUnchanged(resolved,session,result,format)){return result}const continuationReadyResult=attachValidateDiagnosticRowContract(resolved.command,result);const bindingBudget=resolveBindingReadOutputBudget(resolved,session);let projected=projectReadOutputRows(continuationReadyResult,resolved,session,cursor);const receipt={contract_version:1,command:resolved.command,requested_dimensions:requested,...bindingBudget?.source==="default"?{budget_source:bindingBudget.source,budget_tokens:bindingBudget.tokens}:{},precedence:resolved.precedence,...canonicalReadOutputReceiptFields(resolved),legacy_aliases_used:resolved.legacy_aliases_used,migration_hints:resolved.migration_hints,estimated_tokens:0,within_budget:true,strings_compacted:false,rows_compacted:false,result_omitted:false};projected.read_output=receipt;projected=session===void 0?projected:attachReadOutputSessionContracts(projected,session,receipt,format);updateReadOutputReceiptEstimate(projected,receipt,format);if(bindingBudget!==void 0&&receipt.estimated_tokens>bindingBudget.tokens){const brief=projectReadOutputItemToBrief(resolved.command,options,projected);if(brief!==void 0){receipt.applied_depth="brief";receipt.degradation_reason="output_budget_reached";projected=stabilizeReadOutputReceiptEstimates(brief,options)}if(receipt.estimated_tokens>bindingBudget.tokens){projected=compactReadOutputProjection(projected,resolved,receipt,bindingBudget,session,captureReadOutputContinuationState(projected,resolved.command,cursor,options),receipt.estimated_tokens,format)}}if(bindingBudget!==void 0&&receipt.estimated_tokens>bindingBudget.tokens){return omitReadOutputForBudget(resolved,requested,session,bindingBudget,receipt.estimated_tokens,format)}return projected}function isReadOutputBudgetExceeded(result){return isRecord(result)&&isRecord(result.output_budget_exceeded)&&result.output_budget_exceeded.omitted_result===true&&result.output_budget_exceeded.reason==="requested_budget_infeasible"}function resolveReadOutputEncoding(command,options){const encoding=resolveReadOutputDimensions(command,options)?.encoding;return encoding?.value==="json"||encoding?.value==="toon"?encoding.value:void 0}export{PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS,PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES,PM_READ_OUTPUT_DIMENSIONS,PM_READ_OUTPUT_OPTION_FLAGS,PM_READ_OUTPUT_SURFACES,PM_READ_OUTPUT_SURFACE_CONTRACTS,applyReadOutputDimensions,applyReadOutputIncludeModes,decodeReadOutputContinuationCursor2 as decodeReadOutputContinuationCursor,encodeReadOutputContinuationCursor2 as encodeReadOutputContinuationCursor,isReadOutputBudgetExceeded,normalizeReadOutputIncludeModeOptions,readOutputCollectionFingerprint2 as readOutputCollectionFingerprint,readOutputIncludeModeOptions,resolveReadOutputDimensions,resolveReadOutputEncoding,resolveReadOutputRecoveryBudget2 as resolveReadOutputRecoveryBudget,resolveReadOutputSurface,stabilizeReadOutputReceiptEstimates,validateReadOutputOptions};
|
|
1
|
+
!(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]="8a044fa0-4028-5527-b6ff-43ec995e8830")}catch(e2){}})();import{resolvePmHistoryOperation}from"./cli-contracts/command-aliases.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{compactReadOutputToBudget,estimateReadOutputTokens,projectReadOutputItemToBrief,preserveReadOutputRowContract,resolveReadOutputRecoveryBudget,updateReadOutputReceiptEstimate}from"./read-output-budget.js";import{resolveReadOutputRecoveryBudget as resolveReadOutputRecoveryBudget2}from"./read-output-budget.js";import{resolvePmCommandOutputBudget}from"./cli-contracts/agent-output-contracts.js";import{boundReadOutputRows,countReadOutputRows,mapReadOutputRows,readOutputBudgetCollections,readOutputContinuationRowCollections,readOutputRowPaths,readOutputRowCollections}from"./read-output-rows.js";import{applyReadOutputContinuation,decodeReadOutputContinuationCursor,encodeReadOutputContinuationCursor,prioritizeAssuranceAssertions,readOutputCollectionFingerprint}from"./read-output/continuation.js";import{decodeReadOutputContinuationCursor as decodeReadOutputContinuationCursor2,encodeReadOutputContinuationCursor as encodeReadOutputContinuationCursor2,PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES,readOutputCollectionFingerprint as readOutputCollectionFingerprint2}from"./read-output/continuation.js";import{applyReadOutputSessionReferences,attachReadOutputSessionReceipt,parseReadOutputSession,readOutputSessionRemainingTokens}from"./read-output-session.js";import{decodeQueryCursorEnvelope,encodeQueryCursor}from"./pagination.js";const PM_READ_OUTPUT_DIMENSIONS=["include","amount","cost","encoding"];const PM_READ_OUTPUT_SURFACES=["list","context","search","get","next","health","deps","graph","history","activity","validate","events","contracts","comments","notes","files","docs","stats","aggregate","duplicates","package-catalog","package-manage","comments-audit","assurance"];const READ_OUTPUT_PRECEDENCE=["canonical","legacy","intent","default"];const CANONICAL_OPTIONS={include:"--output-include",amount:"--output-limit",cost:"--output-budget",encoding:"--output-format"};const READ_OUTPUT_INVOCATION_PROVENANCE=Symbol.for("pm.readOutputInvocationProvenance");const PM_READ_OUTPUT_OPTION_FLAGS=Object.freeze(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>CANONICAL_OPTIONS[dimension]));const PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS=Object.freeze(["--output-session","--output-cursor","--output-row-contract"]);const LEGACY_FLAGS_BY_COMMAND={list:{include:["--brief","--compact","--fields","--full"],amount:["--after","--limit","--no-truncate"],cost:["--token-budget"],encoding:["--format","--stream"]},context:{include:["--fields","--section"],amount:["--after","--depth","--limit"],cost:["--token-budget"],encoding:["--format"]},search:{include:["--compact","--fields","--full"],amount:["--after","--limit"],cost:["--token-budget"],encoding:["--format"]},get:{include:["--fields","--full"],amount:["--depth"],cost:["--token-budget"],encoding:["--format"]},next:{amount:["--blocked-limit","--limit"],cost:["--token-budget"],encoding:["--format"]},health:{include:["--brief","--check-only","--full","--summary"]},deps:{include:["--collapse","--full","--summary"],amount:["--edge-limit","--max-depth","--node-limit"],cost:["--token-budget"],encoding:["--format"]},graph:{include:["--full","--summary"],amount:["--after","--limit","--max-depth","--max-paths"]},history:{include:["--compact","--full"],amount:["--limit"],encoding:["--format"]},activity:{include:["--compact","--full"],amount:["--limit","--unbounded"],encoding:["--stream"]},validate:{include:["--counts","--full"]},events:{include:["--full"],amount:["--limit"],encoding:["--follow"]},contracts:{include:["--full","--summary"]},comments:{amount:["--limit"]},notes:{amount:["--limit"]},files:{amount:["--limit","--no-truncate","--offset"]},docs:{},stats:{},aggregate:{},duplicates:{amount:["--limit"]},"package-catalog":{},"package-manage":{},"comments-audit":{},assurance:{}};const VALUE_BEARING_INCLUDE_ALIASES=new Set(["--collapse","--fields","--section"]);const BEHAVIOR_PRESERVING_MIGRATION_HINTS=Object.freeze({"--after":"--after retains cursor-position semantics; use --output-limit <n> separately to bound returned rows.","--check-only":"--check-only retains health side-effect semantics; --output-include does not suppress vector refresh.","--collapse":"--collapse retains dependency grouping semantics; --output-include does not replace it.","--depth":"--depth retains traversal or detail-depth semantics; --output-limit does not replace it.","--follow":"--follow retains event-tail semantics; --output-format does not enable following.","--max-depth":"--max-depth retains graph traversal-depth semantics; --output-limit does not replace it.","--max-paths":"--max-paths retains graph path-search semantics; use --output-limit separately to bound returned rows.","--no-truncate":"--no-truncate is a compatibility alias; prefer --output-limit unbounded.","--offset":"--offset retains positional pagination semantics; use --output-limit separately to bound returned rows.","--stream":"--stream retains command streaming semantics; --output-format selects only static result encoding.","--unbounded":"--unbounded is a compatibility alias; prefer --output-limit unbounded."});function flagSelector(flag){return flag.slice(2).replaceAll("-","_")}function migrationHint(flag,dimension){const behaviorHint=BEHAVIOR_PRESERVING_MIGRATION_HINTS[flag];if(behaviorHint!==void 0)return behaviorHint;const suffix=dimension==="include"?VALUE_BEARING_INCLUDE_ALIASES.has(flag)?"<csv>":flagSelector(flag):dimension==="amount"?"<n>":dimension==="cost"?"<tokens>":"<toon|json>";return`${flag} is a compatibility alias; prefer ${CANONICAL_OPTIONS[dimension]} ${suffix}.`}function buildSurfaceContract(command){const legacy=LEGACY_FLAGS_BY_COMMAND[command];const dimensions=Object.freeze(Object.fromEntries(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>[dimension,Object.freeze({dimension,canonical_option:CANONICAL_OPTIONS[dimension],applicable:true,inapplicable_reason:null,legacy_aliases:Object.freeze((legacy[dimension]??[]).map(flag=>Object.freeze({flag,semantics:BEHAVIOR_PRESERVING_MIGRATION_HINTS[flag]===void 0?"replacement":"behavior_preserving",migration_hint:migrationHint(flag,dimension),visibility:"hidden_alias"})))})])));return Object.freeze({command,dimensions,precedence:READ_OUTPUT_PRECEDENCE,budget_retention_policy:command==="assurance"?"verdict_priority":"ordered_prefix",projection_modes:Object.freeze([...readOutputIncludeModeOptions(command).keys()])})}const PM_READ_OUTPUT_SURFACE_CONTRACTS=Object.freeze(PM_READ_OUTPUT_SURFACES.map(buildSurfaceContract));const SURFACE_CONTRACT_BY_COMMAND=new Map(PM_READ_OUTPUT_SURFACE_CONTRACTS.map(contract=>[contract.command,contract]));function resolveReadOutputSurface(command,options={}){const normalizedCommand=resolvePmHistoryOperation(command.trim().toLowerCase());const packageMode=normalizedCommand==="package catalog"||normalizedCommand==="packages catalog"||normalizedCommand==="package-catalog"||(normalizedCommand==="package"||normalizedCommand==="packages"||normalizedCommand==="extension")&&(options.catalog===true||options.target==="catalog"||options.action==="catalog");const root=packageMode?"package-catalog":normalizedCommand==="package manage"||normalizedCommand==="package-manage"?"package-manage":normalizedCommand.split(" ")[0];const normalized=root.startsWith("list-")?"list":root==="ctx"?"context":root;return PM_READ_OUTPUT_SURFACES.includes(normalized)?normalized:void 0}const CANONICAL_OPTION_KEYS=["outputInclude","output_include","outputLimit","output_limit","outputBudget","output_budget","outputFormat","output_format","outputSession","output_session","outputCursor","output_cursor","outputRowContract","output_row_contract"];const HYBRID_READ_MUTATION_KEYS={comments:["add","body","stdin","file","edit","delete"],notes:["add","addJson","stdin","file","edit","delete"],files:["add","addGlob","remove","migrate","apply","note"],docs:["add","addGlob","remove","migrate","note"],"package-catalog":["activate","adopt","adoptAll","deactivate","doctor","init","install","manage","migrate","reload","scaffold","uninstall"]};function hasCanonicalReadOutputOptions(options){return CANONICAL_OPTION_KEYS.some(key=>key!=="outputFormat"&&key!=="output_format"&&options[key]!==void 0)}const READ_OUTPUT_VALUE_VALIDATORS=[{keys:["outputInclude","output_include"],valid:value=>stringList(value)!==void 0,message:"--output-include requires at least one comma-separated field or section."},{keys:["outputLimit","output_limit"],valid:value=>value==="unbounded"||positiveInteger(value)!==void 0,message:"--output-limit must be a positive integer or unbounded."},{keys:["outputBudget","output_budget"],valid:value=>value==="unbounded"||positiveInteger(value)!==void 0,message:"--output-budget must be a positive integer or unbounded."},{keys:["outputSession","output_session"],valid:value=>{parseReadOutputSession(value);return true},message:"--output-session must be a valid session-state object."},{keys:["outputCursor","output_cursor"],valid:value=>typeof value==="string"&&value.trim().length>0,message:"--output-cursor requires a non-empty continuation cursor."}];function validateReadOutputOptions(command,options){const encoding=options.outputFormat??options.output_format;if(encoding!==void 0&&encoding!=="json"&&encoding!=="toon"){throw new PmCliError("--output-format must be toon or json.",EXIT_CODE.USAGE)}if(!hasCanonicalReadOutputOptions(options))return;const normalizedCommand=resolveReadOutputSurface(command,options);if(!normalizedCommand){throw new PmCliError(`Universal output controls apply only to read commands; ${command||"this command"} is not a read surface.`,EXIT_CODE.USAGE)}if((HYBRID_READ_MUTATION_KEYS[normalizedCommand]??[]).some(key=>options[key]!==void 0&&options[key]!==false)){throw new PmCliError(`Universal output controls cannot be combined with a ${normalizedCommand} mutation.`,EXIT_CODE.USAGE)}for(const validator of READ_OUTPUT_VALUE_VALIDATORS){const value=validator.keys.map(key=>options[key]).find(entry=>entry!==void 0);if(value!==void 0&&!validator.valid(value)){throw new PmCliError(validator.message,EXIT_CODE.USAGE)}}}function readOutputIncludeModeOptions(command){const surface=resolveReadOutputSurface(command);if(!surface)return new Map;return new Map((LEGACY_FLAGS_BY_COMMAND[surface].include??[]).filter(flag=>!VALUE_BEARING_INCLUDE_ALIASES.has(flag)&&BEHAVIOR_PRESERVING_MIGRATION_HINTS[flag]===void 0).map(flag=>[flagSelector(flag),optionKey(flag)]))}function applyReadOutputIncludeModes(command,includeValue,commandOptions){const requested=stringList(includeValue)??[];const modeOptions=readOutputIncludeModeOptions(command);const selectors=[];const modes=[];const optionsWithProvenance=commandOptions;const existingProvenance=optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE];const canonicalModes=new Set(existingProvenance?.canonical_include_modes??[]);const explicitLegacyAliases=new Set(existingProvenance?.explicit_legacy_aliases??[]);for(const token of requested){const option=modeOptions.get(token);if(option===void 0){selectors.push(token);continue}const legacyFlag=`--${token.replaceAll("_","-")}`;if(isRequestedOption(readOption(commandOptions,legacyFlag))){explicitLegacyAliases.add(legacyFlag)}commandOptions[option]=true;modes.push(token);canonicalModes.add(token)}const forwardedGetFieldSelectors=resolveReadOutputSurface(command)==="get"?selectors.filter(selector=>selector!=="item"):[];const forwardedGetFields=forwardedGetFieldSelectors.length>0;if(forwardedGetFields){commandOptions.fields=[...new Set([...stringList(commandOptions.fields)??[],...forwardedGetFieldSelectors])].join(",");canonicalModes.add("fields")}if(modes.length>0||forwardedGetFields){optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE]={canonical_include_modes:[...canonicalModes],explicit_legacy_aliases:[...explicitLegacyAliases],...existingProvenance?.cli_invocation_observed===true?{cli_invocation_observed:true}:{}}}return{selectors,modes}}function normalizeReadOutputIncludeModeOptions(command,options){const include=options.outputInclude??options.output_include;if(include===void 0)return;const{selectors,modes}=applyReadOutputIncludeModes(command,include,options);if(modes.length===0)return;const residual=selectors.length>0?selectors.join(","):void 0;options.outputInclude=residual;if(Object.hasOwn(options,"output_include")){options.output_include=residual}}function optionKey(flag){return flag.slice(2).replace(/-([a-z])/gu,(_,character)=>character.toUpperCase())}function readOption(options,flag){const key=optionKey(flag);if(Object.hasOwn(options,key))return options[key];const snakeKey=flag.slice(2).replaceAll("-","_");if(Object.hasOwn(options,snakeKey))return options[snakeKey];if(flag==="--no-truncate"&&options.truncate===false)return true;return void 0}function isRequestedOption(value){return value!==void 0&&value!==false&&value!==null}function stringList(value){const values=Array.isArray(value)?value:[value];const normalized=values.flatMap(entry=>typeof entry==="string"?entry.split(","):[]).map(entry=>entry.trim()).filter(Boolean);return normalized.length>0?[...new Set(normalized)]:void 0}function positiveInteger(value){const parsed=typeof value==="number"?value:typeof value==="string"&&/^\d+$/u.test(value.trim())?Number(value):Number.NaN;return Number.isSafeInteger(parsed)&&parsed>0?parsed:void 0}function resolveLegacyDimension(contract,options,usable,ignore){for(const alias of contract.legacy_aliases){if(ignore(alias.flag))continue;const value=readOption(options,alias.flag);const candidate={value,flag:alias.flag};if(isRequestedOption(value)&&usable(candidate))return candidate}return void 0}function resolveIncludeValue(canonical,legacy){const canonicalList=stringList(canonical);if(canonicalList)return{source:"canonical",value:canonicalList};if(!legacy)return void 0;return{source:"legacy",value:stringList(legacy.value)??[flagSelector(legacy.flag)]}}function resolveAmountValue(canonical,legacy){if(canonical==="unbounded"){return{source:"canonical",value:"unbounded"}}const canonicalLimit=positiveInteger(canonical);if(canonicalLimit!==void 0){return{source:"canonical",value:canonicalLimit}}if(!legacy)return void 0;if(legacy.flag==="--no-truncate"||legacy.flag==="--unbounded"){return{source:"legacy",value:"unbounded"}}const legacyLimit=positiveInteger(legacy.value);return legacyLimit===void 0?void 0:{source:"legacy",value:legacyLimit}}function resolveCostValue(canonical,legacy){if(canonical==="unbounded"){return{source:"canonical",value:"unbounded"}}const canonicalBudget=positiveInteger(canonical);if(canonicalBudget!==void 0){return{source:"canonical",value:canonicalBudget}}if(!legacy)return void 0;const legacyBudget=positiveInteger(legacy.value);return legacyBudget===void 0?void 0:{source:"legacy",value:legacyBudget}}function resolveEncodingValue(canonical,legacy){if(canonical==="json"||canonical==="toon"){return{source:"canonical",value:canonical}}if(!legacy)return void 0;if(legacy.flag==="--stream"||legacy.flag==="--follow"){return{source:"legacy",value:"stream"}}return legacy.value==="json"||legacy.value==="toon"?{source:"legacy",value:legacy.value}:void 0}function shouldIgnoreReadOutputLegacyAlias(provenance,dimension,flag){if(!provenance)return false;const explicitLegacyAliases=new Set(provenance.explicit_legacy_aliases);if(provenance.cli_invocation_observed===true){return!explicitLegacyAliases.has(flag)}const forwardedIncludeAliases=new Set(provenance.canonical_include_modes.map(mode=>`--${mode.replaceAll("_","-")}`));return dimension==="include"&&forwardedIncludeAliases.has(flag)&&!explicitLegacyAliases.has(flag)}function hasCompleteReadOutputIntent(command,legacyByDimension,provenance){const root=command.trim().toLowerCase().replaceAll(/\s+/gu," ").split(" ")[0];return root==="list-all"||legacyByDimension.amount?.flag==="--no-truncate"||legacyByDimension.include?.flag==="--full"||provenance?.canonical_include_modes.includes("full")===true}function canonicalReadOutputOptionsUsed(resolvedByDimension,provenance){return PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>resolvedByDimension[dimension]?.source==="canonical"||dimension==="include"&&(provenance?.canonical_include_modes.length??0)>0?[CANONICAL_OPTIONS[dimension]]:[])}function resolveReadOutputDimensions(command,options){const normalizedCommand=resolveReadOutputSurface(command,options);if(!normalizedCommand)return void 0;const contract=SURFACE_CONTRACT_BY_COMMAND.get(normalizedCommand);const invocationProvenance=options[READ_OUTPUT_INVOCATION_PROVENANCE];const legacyResolvers={include:candidate=>resolveIncludeValue(void 0,candidate),amount:candidate=>resolveAmountValue(void 0,candidate),cost:candidate=>resolveCostValue(void 0,candidate),encoding:candidate=>resolveEncodingValue(void 0,candidate)};const legacyByDimension=Object.fromEntries(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>[dimension,resolveLegacyDimension(contract.dimensions[dimension],options,candidate=>legacyResolvers[dimension](candidate)!==void 0,flag=>shouldIgnoreReadOutputLegacyAlias(invocationProvenance,dimension,flag))]));const legacyAliasesUsed=PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>{const resolved=legacyByDimension[dimension];return resolved?[resolved.flag]:[]});const migrationHints=PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>{const resolved=legacyByDimension[dimension];if(!resolved)return[];const alias=contract.dimensions[dimension].legacy_aliases.find(entry=>entry.flag===resolved.flag);return[alias.migration_hint]});const encoding=resolveEncodingValue(options.outputFormat??options.output_format,legacyByDimension.encoding);const include=resolveIncludeValue(options.outputInclude??options.output_include,legacyByDimension.include);const amount=resolveAmountValue(options.outputLimit??options.output_limit,legacyByDimension.amount);const explicitCost=resolveCostValue(options.outputBudget??options.output_budget,legacyByDimension.cost);const completeResultIntent=hasCompleteReadOutputIntent(command,legacyByDimension,invocationProvenance);const budget=resolvePmCommandOutputBudget(command,{generateFallback:true});const resolvedOutputFormat=encoding?.value==="json"||options.resolvedOutputFormat==="json"?"json":"toon";const cost=explicitCost??(completeResultIntent?{source:"intent",value:"unbounded"}:{source:"default",value:budget.default_max_estimated_tokens_by_format[resolvedOutputFormat]});const resolvedByDimension={include,amount,cost,encoding};return{command:normalizedCommand,include,amount,cost,encoding,canonical_options_used:canonicalReadOutputOptionsUsed(resolvedByDimension,invocationProvenance),legacy_aliases_used:legacyAliasesUsed,migration_hints:migrationHints,precedence:READ_OUTPUT_PRECEDENCE}}function isRecord(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)}const ENVELOPE_KEYS=new Set(["applied_bound","applied_limit","completeness","continuation_kind","continuation_path","continuation_contract","count","filters","has_more","next_cursor","now","omission_receipt","projection","budget_retention_policy","row_contract","sorting","total","truncated"]);const GET_STABLE_DERIVED_ITEM_SELECTORS=["collection_counts","notes_count","tests_count"];function projectRecordFields(value,selectors){const selected=new Set(selectors.map(selector=>selector.split(".")[0]));return Object.fromEntries(Object.entries(value).filter(([key])=>selected.has(key)))}function getProjectionVocabulary(result){const item=isRecord(result.item)?result.item:{};const itemFields=[...new Set([...Object.keys(item),...GET_STABLE_DERIVED_ITEM_SELECTORS.filter(key=>Object.hasOwn(item,key))])].sort((left,right)=>left.localeCompare(right));const sections=Object.keys(result).filter(key=>key!=="item"&&key!=="read_output"&&!ENVELOPE_KEYS.has(key)).sort((left,right)=>left.localeCompare(right));return{item,itemFields,sections,valid:[...itemFields,"item",...itemFields.map(field=>`item.${field}`),...sections]}}function applyGetIncludeProjection(result,selectors){const vocabulary=getProjectionVocabulary(result);const unknown=selectors.filter(selector=>!vocabulary.valid.includes(selector));if(unknown.length>0){throw new PmCliError(`Unknown --output-include selector(s) for get: ${unknown.join(", ")}. Valid selectors: ${vocabulary.valid.join(", ")}.`,EXIT_CODE.USAGE)}const fullItem=selectors.includes("item");const itemSelectors=selectors.flatMap(selector=>selector.startsWith("item.")?[selector.slice("item.".length)]:vocabulary.itemFields.includes(selector)?[selector]:[]).filter((selector,index,values)=>values.indexOf(selector)===index);if(fullItem&&itemSelectors.length>0){throw new PmCliError("--output-include cannot mix a full item with projected item fields; use item or item.<field>, not both.",EXIT_CODE.USAGE)}const selectedSections=new Set(selectors.filter(selector=>vocabulary.sections.includes(selector)));const projected=Object.fromEntries(Object.entries(result).filter(([key])=>ENVELOPE_KEYS.has(key)||selectedSections.has(key)));if(fullItem){projected.item=vocabulary.item}else if(itemSelectors.length>0){projected.item=projectRecordFields(vocabulary.item,itemSelectors)}const omittedFieldGroups=[...fullItem?[]:itemSelectors.length>0?vocabulary.itemFields.filter(field=>!itemSelectors.includes(field)).map(field=>({name:`item.${field}`,restore_with:`--output-include item.${field}`})):[{name:"item",restore_with:"--output-include item"}],...vocabulary.sections.filter(section=>!selectedSections.has(section)).map(section=>({name:section,restore_with:`--output-include ${section}`}))];const inheritedOmittedFieldGroups=isRecord(projected.omission_receipt)&&Array.isArray(projected.omission_receipt.omitted_field_groups)?projected.omission_receipt.omitted_field_groups:[];const combinedOmittedFieldGroups=[...inheritedOmittedFieldGroups,...omittedFieldGroups];projected.omission_receipt={has_omissions:combinedOmittedFieldGroups.length>0,omitted_field_group_count:combinedOmittedFieldGroups.length,omitted_field_groups:combinedOmittedFieldGroups};return projected}function countPopulatedRows(result){let populated=0;mapReadOutputRows({...result},entry=>{if(isRecord(entry)&&Object.keys(entry).length>0)populated+=1;return entry});return populated}function rejectEmptyIncludeProjection(command,original,shaped,selectors){if(countPopulatedRows(original)===0||countPopulatedRows(shaped)>0){return}const modes=[...readOutputIncludeModeOptions(command).keys()];const domain=modes.length>0?` Declared ${command} projection modes: ${modes.join(", ")}.`:` The ${command} surface declares no projection modes; name row fields instead.`;throw new PmCliError(`Unknown --output-include selector(s) for ${command}: ${selectors.join(", ")}. No selector matched any returned row field.${domain}`,EXIT_CODE.USAGE)}function applyIncludeProjection(command,result,selectors){if(command==="get"){return applyGetIncludeProjection(result,selectors)}const rows=readOutputRowPaths(result);const qualifiedRowSelectors=selectors.flatMap(selector=>rows.flatMap(rowPath=>selector.startsWith(`${rowPath}.`)?[selector.slice(rowPath.length+1)]:[]));const selectedRoot=selectors.some(selector=>Object.hasOwn(result,selector.split(".")[0])&&!rows.some(rowPath=>selector.startsWith(`${rowPath}.`)));if(rows.length>0&&(!selectedRoot||qualifiedRowSelectors.length>0)){const projected={...result};const rowSelectors=qualifiedRowSelectors.length>0?qualifiedRowSelectors:selectors;const shaped=mapReadOutputRows(projected,entry=>isRecord(entry)?projectRecordFields(entry,rowSelectors):entry);rejectEmptyIncludeProjection(command,result,shaped,rowSelectors);return shaped}return Object.fromEntries(Object.entries(result).filter(([key])=>selectors.some(selector=>selector.split(".")[0]===key)||ENVELOPE_KEYS.has(key)))}function applyAmountBound(result,amount){if(amount==="unbounded")return result;const{result:bounded,truncated}=boundReadOutputRows(result,amount);if(!truncated)return bounded;bounded.has_more=true;bounded.truncated=true;if(typeof bounded.count==="number"){bounded.count=countReadOutputRows(bounded)}bounded.applied_bound={kind:"output_limit",source:"explicit",value:amount};return bounded}function requestedDimensions(resolved){return PM_READ_OUTPUT_DIMENSIONS.filter(dimension=>resolved[dimension]!==void 0&&resolved[dimension]?.source!=="default"||resolved.canonical_options_used.includes(CANONICAL_OPTIONS[dimension]))}function readOutputMeasurementFormat(options){const format=options.resolvedOutputFormat??options.outputFormat??options.output_format??options.format;return format==="json"||format==="toon"?format:void 0}function attachReadOutputSessionContracts(result,state,receipt,format){let withSession=attachReadOutputSessionReceipt(result,state,format);preserveReadOutputRowContract(result,withSession);for(let iteration=0;iteration<8;iteration+=1){const previousReadEstimate=receipt.estimated_tokens;const previousSessionEstimate=withSession.read_session.spent_this_call_tokens;updateReadOutputReceiptEstimate(withSession,receipt,format);const previous=withSession;withSession=attachReadOutputSessionReceipt(withSession,state,format);preserveReadOutputRowContract(previous,withSession);const sessionEstimate=withSession.read_session.spent_this_call_tokens;if(receipt.estimated_tokens===previousReadEstimate&&sessionEstimate===previousSessionEstimate){return withSession}}return withSession}function stabilizeReadOutputReceiptEstimates(result,options){if(!isRecord(result.read_output))return result;const format=readOutputMeasurementFormat(options);const receipt=result.read_output;const session=parseReadOutputSession(options.outputSession??options.output_session);if(session===void 0){updateReadOutputReceiptEstimate(result,receipt,format);return result}return attachReadOutputSessionContracts(result,session,receipt,format)}function attachValidateDiagnosticRowContract(command,result){if(command!=="validate")return result;const projection=isRecord(result.projection)?result.projection:void 0;const declaredFieldGroups=Array.isArray(projection?.declared_field_groups)?projection.declared_field_groups:[];if(!declaredFieldGroups.some(group=>isRecord(group)&&group.name==="diagnostic_rows")){return result}const diagnosticCollectionPaths=[...new Set(readOutputBudgetCollections(result).map(({path})=>path).filter(path=>/^checks\.\d+\.details\./u.test(path)))];const diagnosticRowKeys=diagnosticCollectionPaths.filter(path=>!diagnosticCollectionPaths.some(candidate=>candidate!==path&&path.startsWith(`${candidate}.`)));if(diagnosticRowKeys.length===0)return result;const existingContract=isRecord(result.row_contract)?result.row_contract:{};const existingRowKeys=Array.isArray(existingContract.row_keys)?existingContract.row_keys.filter(entry=>typeof entry==="string"):[];const existingContinuationRowKeys=Array.isArray(existingContract.continuation_row_keys)?existingContract.continuation_row_keys.filter(entry=>typeof entry==="string"):[];const rowKeys=existingRowKeys.length>0?existingRowKeys:diagnosticRowKeys;const continuationRowKeys=[...new Set(diagnosticRowKeys)];return JSON.stringify(rowKeys)===JSON.stringify(existingRowKeys)&&JSON.stringify(continuationRowKeys)===JSON.stringify(existingContinuationRowKeys)?result:{...result,row_contract:{...existingContract,row_keys:rowKeys,continuation_row_keys:continuationRowKeys,jq_selector:typeof existingContract.jq_selector==="string"?existingContract.jq_selector:".checks[].details"}}}function projectReadOutputRows(result,resolved,session,cursor){let projected={...result};if(resolved.include?.source==="canonical"){projected=applyIncludeProjection(resolved.command,projected,resolved.include.value)}if(resolved.command==="assurance"){projected=prioritizeAssuranceAssertions(projected)}projected=applyReadOutputContinuation(projected,resolved.command,cursor);if(resolved.amount?.source==="canonical"){projected=applyAmountBound(projected,resolved.amount.value)}return session===void 0?projected:applyReadOutputSessionReferences(projected,session)}function resolveBindingReadOutputBudget(resolved,session){const budgets=[...resolved.cost!==void 0&&resolved.cost.value!=="unbounded"&&(resolved.cost.source==="canonical"||resolved.cost.source==="default")?[{source:resolved.cost.source,tokens:resolved.cost.value}]:[],...session===void 0?[]:[{source:"session",tokens:readOutputSessionRemainingTokens(session)}]];return budgets.sort((left,right)=>left.tokens-right.tokens)[0]}function canonicalReadOutputReceiptFields(resolved){const canonicalOptions=resolved.canonical_options_used;return canonicalOptions&&canonicalOptions.length>0?{canonical_options_used:canonicalOptions}:{}}function omitReadOutputForBudget(resolved,requested,session,bindingBudget,omittedResultEstimatedTokens,format){const minimalReceipt={contract_version:1,command:resolved.command,requested_dimensions:requested,...bindingBudget.source==="default"?{budget_source:bindingBudget.source,budget_tokens:bindingBudget.tokens}:{},precedence:resolved.precedence,...canonicalReadOutputReceiptFields(resolved),legacy_aliases_used:[],migration_hints:[],estimated_tokens:0,within_budget:false,strings_compacted:false,rows_compacted:false,result_omitted:true,...session===void 0?{omitted_result_estimated_tokens:omittedResultEstimatedTokens}:{}};const omitted={output_budget_exceeded:{omitted_result:true,reason:"requested_budget_infeasible",restore_with:"Unbounded",recovery:{outputBudget:"unbounded"}},read_output:minimalReceipt};const boundedOmission=session===void 0?omitted:attachReadOutputSessionContracts(omitted,session,minimalReceipt,format);if(session===void 0){updateReadOutputReceiptEstimate(boundedOmission,minimalReceipt,format)}if(session!==void 0&&minimalReceipt.estimated_tokens>bindingBudget.tokens){throw new PmCliError("The remaining output-session budget cannot fit its mandatory receipts; start a new session with a larger token_budget.",EXIT_CODE.USAGE)}return boundedOmission}function requiresReadOutputAudit(resolved,options){return options.outputRowContract===true||options.output_row_contract===true||resolved.canonical_options_used.includes("--output-include")||resolved.command==="list"&&resolved.canonical_options_used.length>0&&resolved.include?.value.includes("full")===true}function canReturnReadOutputUnchanged(resolved,session,result,format,options){if(session!==void 0||requiresReadOutputAudit(resolved,options))return false;if(resolved.amount?.source==="canonical"&&resolved.amount.value!=="unbounded"){const limit=resolved.amount.value;if(readOutputRowCollections(result).some(({value})=>(Array.isArray(value)?value.length:Object.keys(value).length)>limit))return false}return resolved.cost===void 0||resolved.cost.value==="unbounded"||resolved.cost.source==="legacy"||estimateReadOutputTokens(options.outputRowContract===false?Object.fromEntries(Object.entries(result).filter(([key])=>key!=="row_contract")):result,format)<=resolved.cost.value}function attachReadOutputTruncationDisclosure(projected,resolved,receipt,bindingBudget,continuationCursorRebased,measuredResultTokens,collectionsBeforeBudget){if(!receipt.rows_compacted)return;const overridden=resolved.amount?.value==="unbounded"?["amount"]:[];const afterByPath=new Map(readOutputContinuationRowCollections(projected).map(collection=>[collection.path,Array.isArray(collection.value)?collection.value.length:Object.keys(collection.value).length]));const continuations=[...collectionsBeforeBudget.entries()].flatMap(([path,before])=>{const retainedRows=afterByPath.get(path);if(retainedRows>=before.rows)return[];const offset=before.baseOffset+retainedRows;return[{path,cursor:encodeReadOutputContinuationCursor({command:resolved.command,path,offset,total_rows:before.totalRows,fingerprint:before.fingerprint}),retained_rows:retainedRows,remaining_rows:before.totalRows-offset,total_rows:before.totalRows}]});const primary=continuations[0];const continuationHint=primary?"; page --output-cursor":"";const budgetHint=bindingBudget.source==="session"?`Truncated by the remaining ${bindingBudget.tokens}-token session budget; start a new output session with a larger token_budget${continuationHint}.`:`${bindingBudget.tokens}-token: raise --output-budget${continuationHint}`;receipt.migration_hints=[budgetHint,...resolved.migration_hints];const recoveryBudget=resolveReadOutputRecoveryBudget({effective_budget_tokens:bindingBudget.tokens,measured_result_tokens:measuredResultTokens});if(primary&&!continuationCursorRebased&&(typeof projected.next_cursor!=="string"||projected.continuation_kind==="output_cursor")){projected.next_cursor=primary.cursor}projected.continuation_kind=continuationCursorRebased?"producer_cursor":primary?"output_cursor":"none";projected.output_budget_truncation={reason:"output_budget_reached",budget_source:bindingBudget.source,budget_tokens:bindingBudget.tokens,overridden_dimensions:overridden,compacted_row_paths:receipt.compacted_row_paths,continuation_cursor_rebased:continuationCursorRebased,continuation_available:continuations.length>0,recovery_budget_multiplier:primary?1:recoveryBudget.recovery_budget_multiplier,continuations,restore_with:primary?"recovery":`Retry with --output-budget ${recoveryBudget.output_budget} because no declared row collection can be continued.`,recovery:primary?{cursor:primary.cursor,cli:"--output-cursor",sdk:"outputCursor",mcp:"outputCursor"}:{cli:`--output-budget ${recoveryBudget.output_budget}`,sdk:{outputBudget:recoveryBudget.output_budget},mcp:{outputBudget:recoveryBudget.output_budget}}}}function rebaseBudgetCompactedCursor(projected,originalItemCount,cursorSource,cursorContinuesExistingPage){if(typeof cursorSource!=="string"||!Array.isArray(projected.items)){return false}const retainedCount=projected.items.length;if(retainedCount===0||retainedCount>=originalItemCount){return false}let cursor;try{cursor=decodeQueryCursorEnvelope(cursorSource)}catch{return false}const sourceIndex=cursor.after_index;if(sourceIndex===void 0)return false;const last=projected.items.at(-1);if(Object.prototype.toString.call(last)!=="[object Object]"){return false}const lastId=Reflect.get(last,"id");if(typeof lastId!=="string"||lastId.length===0)return false;const afterIndex=cursorContinuesExistingPage?sourceIndex-(originalItemCount-retainedCount):sourceIndex+retainedCount;if(afterIndex<0)return false;projected.next_cursor=encodeQueryCursor(cursor.fingerprint,lastId,afterIndex,cursor.snapshot);return true}function captureReadOutputContinuationState(projected,command,cursor,options){const collectionsBeforeBudget=new Map(readOutputContinuationRowCollections(projected).map(collection=>{const rows=Array.isArray(collection.value)?collection.value.length:Object.keys(collection.value).length;const continued=cursor?.path===collection.path;return[collection.path,{rows,totalRows:continued?cursor.total_rows:rows,baseOffset:continued?cursor.offset:0,fingerprint:continued?cursor.fingerprint:readOutputCollectionFingerprint(collection.path,collection.value,command)}]}));const cursorContinuesExistingPage=typeof projected.next_cursor==="string";return{collectionsBeforeBudget,originalItemCount:Array.isArray(projected.items)?projected.items.length:0,cursorContinuesExistingPage,cursorSource:cursorContinuesExistingPage?projected.next_cursor:options.after}}function compactReadOutputProjection(projected,resolved,receipt,bindingBudget,session,continuationState,measuredResultTokens,format){const assuranceMinimumRows=resolved.command==="assurance"&&Array.isArray(projected.assertions)?projected.assertions.filter(row=>isRecord(row)&&row.verdict!=="pass").length:0;return compactReadOutputToBudget(projected,receipt,bindingBudget.tokens,assuranceMinimumRows>0?new Map([["assertions",assuranceMinimumRows]]):new Map,format,compacted=>{const continuationCursorRebased=rebaseBudgetCompactedCursor(compacted,continuationState.originalItemCount,continuationState.cursorSource,continuationState.cursorContinuesExistingPage);attachReadOutputTruncationDisclosure(compacted,resolved,receipt,bindingBudget,continuationCursorRebased,measuredResultTokens,continuationState.collectionsBeforeBudget);if(session!==void 0){Object.assign(compacted,attachReadOutputSessionContracts(compacted,session,receipt,format))}})}function applyReadOutputDimensions(command,options,result){const resolved=resolveReadOutputDimensions(command,options);if(!resolved)return result;const format=readOutputMeasurementFormat(options);const session=parseReadOutputSession(options.outputSession??options.output_session);const rawCursor=options.outputCursor??options.output_cursor;const cursor=typeof rawCursor==="string"?decodeReadOutputContinuationCursor(rawCursor):void 0;const requested=requestedDimensions(resolved);const continuationReadyResult=attachValidateDiagnosticRowContract(resolved.command,result);if(cursor===void 0&&canReturnReadOutputUnchanged(resolved,session,continuationReadyResult,format,options)){return continuationReadyResult}const bindingBudget=resolveBindingReadOutputBudget(resolved,session);let projected=projectReadOutputRows(continuationReadyResult,resolved,session,cursor);preserveReadOutputRowContract(projected,projected,options.outputRowContract===false);const receipt={contract_version:1,command:resolved.command,requested_dimensions:requested,...bindingBudget?.source==="default"?{budget_source:bindingBudget.source,budget_tokens:bindingBudget.tokens}:{},precedence:resolved.precedence,...canonicalReadOutputReceiptFields(resolved),legacy_aliases_used:resolved.legacy_aliases_used,migration_hints:resolved.migration_hints,estimated_tokens:0,within_budget:true,strings_compacted:false,rows_compacted:false,result_omitted:false};projected.read_output=receipt;projected=session===void 0?projected:attachReadOutputSessionContracts(projected,session,receipt,format);updateReadOutputReceiptEstimate(projected,receipt,format);if(bindingBudget!==void 0&&receipt.estimated_tokens>bindingBudget.tokens){const brief=projectReadOutputItemToBrief(resolved.command,options,projected);if(brief!==void 0){receipt.applied_depth="brief";receipt.degradation_reason="output_budget_reached";preserveReadOutputRowContract(projected,brief);projected=stabilizeReadOutputReceiptEstimates(brief,options)}if(receipt.estimated_tokens>bindingBudget.tokens){projected=compactReadOutputProjection(projected,resolved,receipt,bindingBudget,session,captureReadOutputContinuationState(projected,resolved.command,cursor,options),receipt.estimated_tokens,format)}}if(bindingBudget!==void 0&&receipt.estimated_tokens>bindingBudget.tokens){return omitReadOutputForBudget(resolved,requested,session,bindingBudget,receipt.estimated_tokens,format)}return projected}function isReadOutputBudgetExceeded(result){return isRecord(result)&&isRecord(result.output_budget_exceeded)&&result.output_budget_exceeded.omitted_result===true&&result.output_budget_exceeded.reason==="requested_budget_infeasible"}function resolveReadOutputEncoding(command,options){const canonical=options.outputFormat??options.output_format;if(canonical==="json"||canonical==="toon")return canonical;const encoding=resolveReadOutputDimensions(command,options)?.encoding;return encoding?.value==="json"||encoding?.value==="toon"?encoding.value:void 0}export{PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS,PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES,PM_READ_OUTPUT_DIMENSIONS,PM_READ_OUTPUT_OPTION_FLAGS,PM_READ_OUTPUT_SURFACES,PM_READ_OUTPUT_SURFACE_CONTRACTS,applyReadOutputDimensions,applyReadOutputIncludeModes,decodeReadOutputContinuationCursor2 as decodeReadOutputContinuationCursor,encodeReadOutputContinuationCursor2 as encodeReadOutputContinuationCursor,isReadOutputBudgetExceeded,normalizeReadOutputIncludeModeOptions,readOutputCollectionFingerprint2 as readOutputCollectionFingerprint,readOutputIncludeModeOptions,resolveReadOutputDimensions,resolveReadOutputEncoding,resolveReadOutputRecoveryBudget2 as resolveReadOutputRecoveryBudget,resolveReadOutputSurface,stabilizeReadOutputReceiptEstimates,validateReadOutputOptions};
|
|
2
2
|
//# sourceMappingURL=read-output-contracts.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(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]="
|
|
1
|
+
!(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]="999accf0-d4e1-5dc4-92a0-4ea7d745ac48")}catch(e2){}})();import{estimateReadOutputTokens}from"./read-output-budget.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{mapReadOutputRows,readOutputRowCollections}from"./read-output-rows.js";const PM_READ_OUTPUT_SESSION_MIN_TOKENS=256;const PM_READ_OUTPUT_SESSION_MAX_SEEN_ITEM_IDS=1e4;const SESSION_ID_PATTERN=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/u;const ITEM_ID_PATTERN=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;const SESSION_KEYS=new Set(["version","id","token_budget","spent_tokens","seen_item_ids"]);const SESSION_FIELD_VALIDATIONS=[{valid:state=>state.version===1,reason:"version must equal 1."},{valid:state=>typeof state.id==="string"&&SESSION_ID_PATTERN.test(state.id),reason:"id must be 1-64 portable identifier characters."},{valid:state=>Number.isSafeInteger(state.token_budget)&&state.token_budget>=PM_READ_OUTPUT_SESSION_MIN_TOKENS,reason:`token_budget must be a safe integer of at least ${PM_READ_OUTPUT_SESSION_MIN_TOKENS}.`},{valid:state=>Number.isSafeInteger(state.spent_tokens)&&state.spent_tokens>=0&&state.spent_tokens<=state.token_budget,reason:"spent_tokens must be a non-negative safe integer no larger than token_budget."},{valid:state=>Array.isArray(state.seen_item_ids)&&state.seen_item_ids.length<=PM_READ_OUTPUT_SESSION_MAX_SEEN_ITEM_IDS&&state.seen_item_ids.every(id=>typeof id==="string"&&ITEM_ID_PATTERN.test(id)),reason:`seen_item_ids must contain at most ${PM_READ_OUTPUT_SESSION_MAX_SEEN_ITEM_IDS} portable item identifiers.`}];function isRecord(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)}function invalidSession(reason){throw new PmCliError(`--output-session ${reason}`,EXIT_CODE.USAGE,{code:"invalid_read_output_session",field:"outputSession"})}function parseReadOutputSession(value){if(value===void 0)return void 0;let parsed=value;if(typeof value==="string"){try{parsed=JSON.parse(value)}catch{invalidSession("must be a valid JSON object.")}}if(!isRecord(parsed))invalidSession("must be a JSON object.");const unknownKeys=Object.keys(parsed).filter(key=>!SESSION_KEYS.has(key));if(unknownKeys.length>0){invalidSession(`contains unknown field "${unknownKeys.sort()[0]}".`)}const invalidField=SESSION_FIELD_VALIDATIONS.find(validation=>!validation.valid(parsed));if(invalidField!==void 0)invalidSession(invalidField.reason);const seenItemIds=[...new Set(parsed.seen_item_ids)].sort();return{version:1,id:parsed.id,token_budget:parsed.token_budget,spent_tokens:parsed.spent_tokens,seen_item_ids:seenItemIds}}function itemIdFromRow(row){if(!isRecord(row))return void 0;if(typeof row.id==="string")return row.id;if(typeof row.item_id==="string")return row.item_id;return isRecord(row.item)&&typeof row.item.id==="string"?row.item.id:void 0}function summarizeReadOutputSessionRows(result){const deliveredIds=new Set;let suppressedRepeatCount=0;const collections=readOutputRowCollections(result);const declaredPaths=new Set(collections.map(({path})=>path));const additionalCollections=Object.entries(result).flatMap(([path,value])=>Array.isArray(value)&&!declaredPaths.has(path)?[{path,value}]:[]);for(const collection of[...collections,...additionalCollections]){const rows=Array.isArray(collection.value)?collection.value:Object.values(collection.value);for(const row of rows){if(!isRecord(row))continue;if(typeof row.context_ref==="string"){suppressedRepeatCount+=1;continue}const itemId=itemIdFromRow(row);if(itemId!==void 0&&ITEM_ID_PATTERN.test(itemId))deliveredIds.add(itemId)}}return{deliveredIds,suppressedRepeatCount}}function applyReadOutputSessionReferences(result,state){const seen=new Set(state.seen_item_ids);return mapReadOutputRows(result,row=>{const itemId=itemIdFromRow(row);return itemId!==void 0&&seen.has(itemId)?{id:itemId,context_ref:`session:${state.id}:${itemId}`}:row})}function attachReadOutputSessionReceipt(result,state,format){const{deliveredIds,suppressedRepeatCount}=summarizeReadOutputSessionRows(result);const alreadySeen=new Set(state.seen_item_ids);const newlySeen=[...deliveredIds].filter(id=>!alreadySeen.has(id)).sort();const retainedNewIds=newlySeen.slice(0,PM_READ_OUTPUT_SESSION_MAX_SEEN_ITEM_IDS-state.seen_item_ids.length);const nextSeen=[...state.seen_item_ids,...retainedNewIds].sort();const seenItemOverflowCount=newlySeen.length-retainedNewIds.length;const receipt={contract_version:1,id:state.id,measurement_scope:"complete_read_envelope",estimator:"ceil(utf8_bytes / 4)",token_budget:state.token_budget,spent_before_tokens:state.spent_tokens,spent_this_call_tokens:0,charged_this_call_tokens:0,spent_total_tokens:state.spent_tokens,remaining_tokens:state.token_budget-state.spent_tokens,exhausted:false,seen_before_count:state.seen_item_ids.length,new_item_count:deliveredIds.size,...seenItemOverflowCount===0?{}:{seen_item_overflow_count:seenItemOverflowCount},suppressed_repeat_count:suppressedRepeatCount,reference_format:"session:<session-id>:<item-id>",restore_reference_with:"pm get <item-id> --brief",next_state:{version:1,id:state.id,token_budget:state.token_budget,spent_tokens:state.spent_tokens,seen_item_ids:nextSeen}};const withReceipt={...result,read_session:receipt};const applyEstimate=estimate2=>{receipt.spent_this_call_tokens=estimate2;receipt.charged_this_call_tokens=Math.min(state.token_budget-state.spent_tokens,estimate2);receipt.spent_total_tokens=Math.min(state.token_budget,state.spent_tokens+receipt.charged_this_call_tokens);receipt.remaining_tokens=Math.max(0,state.token_budget-receipt.spent_total_tokens);receipt.exhausted=receipt.remaining_tokens<PM_READ_OUTPUT_SESSION_MIN_TOKENS;receipt.next_state.spent_tokens=receipt.spent_total_tokens};let estimate=0;let highestMeasuredEstimate=0;for(let iteration=0;iteration<8;iteration+=1){applyEstimate(estimate);const measured=estimateReadOutputTokens(withReceipt,format);if(measured===estimate)return withReceipt;highestMeasuredEstimate=Math.max(highestMeasuredEstimate,measured);estimate=measured}applyEstimate(highestMeasuredEstimate);return withReceipt}function readOutputSessionRemainingTokens(state){return Math.max(0,state.token_budget-state.spent_tokens)}export{PM_READ_OUTPUT_SESSION_MAX_SEEN_ITEM_IDS,PM_READ_OUTPUT_SESSION_MIN_TOKENS,applyReadOutputSessionReferences,attachReadOutputSessionReceipt,parseReadOutputSession,readOutputSessionRemainingTokens};
|
|
2
2
|
//# sourceMappingURL=read-output-session.js.map
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/test/execution
|
|
3
|
+
*
|
|
4
|
+
* Implements the pm test command surface and its agent-facing runtime behavior.
|
|
5
|
+
*/
|
|
6
|
+
import { readJsonPathValue, splitJsonPathSegments } from "./json-path.js";
|
|
1
7
|
import type { GlobalOptions } from "../../core/shared/command-types.js";
|
|
2
8
|
import { resolveAuthor } from "../../core/shared/author.js";
|
|
3
9
|
import { runInit } from "../init.js";
|
|
@@ -243,11 +249,6 @@ declare function seedMissingLinkedTestSettingsHistory(sourceRoot: string, sandbo
|
|
|
243
249
|
declare function countLinkedTestItemFiles(pmRoot: string): Promise<number>;
|
|
244
250
|
/** Implements resolve linked test failure exit code for the public runtime surface of this module. */
|
|
245
251
|
export declare function resolveLinkedTestFailureExitCode(execution: Pick<LinkedTestExecutionResult, "exitCode" | "timedOut" | "maxBufferExceeded">): number;
|
|
246
|
-
declare function splitJsonPathSegments(fieldPath: string): Array<string | number>;
|
|
247
|
-
declare function readJsonPathValue(root: unknown, fieldPath: string): {
|
|
248
|
-
found: boolean;
|
|
249
|
-
value: unknown;
|
|
250
|
-
};
|
|
251
252
|
declare function evaluateLinkedTestAssertions(linkedTest: LinkedTest, stdout: string, stderr: string): string[];
|
|
252
253
|
/** Return whether a linked command applies a runner-level test-name filter that must match at least one test. */
|
|
253
254
|
declare function commandUsesTestNameFilter(command: string): boolean;
|