@unbrained/pm-cli 2026.10.8 → 2026.10.9
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 +17 -0
- package/dist/cli/register-list-query.js +2 -2
- package/dist/cli-bundle/bundle-manifest.json +151 -151
- package/dist/cli-bundle/chunks/{chunk-ZHIMZ65M.js → chunk-55MK3QQM.js} +30 -30
- package/dist/cli-bundle/chunks/{chunk-34L2BS2Z.js → chunk-5MOFELIF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ZBVAZ7XX.js → chunk-5NR6TDYB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OG66KEOF.js → chunk-5TCQ5J3V.js} +74 -78
- package/dist/cli-bundle/chunks/{chunk-K6E2FFUT.js → chunk-CPZOW6L2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TNU56MZI.js → chunk-E4XR5LKU.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RCFZ6H2Y.js → chunk-KOGF6O6W.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-JDTBPW4Y.js → chunk-N7GKWO4G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-L7U5FSZ5.js → chunk-NIF7JOPW.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-MJVRF67I.js → chunk-P5NS7EFC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HFCIAXLP.js → chunk-QQHNXCO3.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FOLSEOJ2.js → chunk-XW3BLWFF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UGFN5NJ2.js → chunk-ZNXRGATT.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-PYVSPGPV.js → register-list-query-2YOWMNWY.js} +7 -7
- package/dist/cli-bundle/chunks/{register-mutation-WXP3YLIN.js → register-mutation-ILOWFMTV.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-WL25C3NP.js → register-operations-BMK65YM3.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-PFKYNEQI.js → register-setup-24TFFK6N.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-PEBOVLEG.js → chunk-2ATAD56F.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-6TKAFFEB.js → chunk-2CJWTLQG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-EOUORVJA.js → chunk-362645PL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-V3EPBB6V.js → chunk-AU6VJGTY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-L3CZNKZE.js → chunk-B3YW6H2I.js} +16 -20
- package/dist/cli-bundle/focused-chunks/{chunk-XT7JAVHI.js → chunk-DMSADMEU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-2KSPGWLH.js → chunk-DSLNUL2Q.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-A3W6HFFO.js → chunk-EZ4367G4.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-MW2TQHZ3.js → chunk-IARAEFMA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-OSKXYRYZ.js → chunk-MCVWZUGK.js} +27 -27
- package/dist/cli-bundle/focused-chunks/{chunk-F2ME5MJY.js → chunk-PBCYGO7X.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-PBPPIGUL.js → chunk-PLTTMQAW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-OLCJ2PJS.js → chunk-SAN3KPX4.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-DRHJOG5X.js → chunk-W5AE7GKZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-LZQGEVKT.js → chunk-WAOXID5J.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-BDT5EALU.js → chunk-WOEZJUA2.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 +1 -1
- package/dist/cli-bundle/sdk-core.js +22 -22
- 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 +50 -50
- 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 +7 -7
- package/dist/core/history/event-index.d.ts +1 -2
- package/dist/core/history/event-index.js +2 -2
- package/dist/core/output/output.d.ts +16 -14
- package/dist/core/output/output.js +6 -10
- package/dist/core/store/item-metadata-query-index.d.ts +1 -2
- package/dist/core/store/item-metadata-query-index.js +1 -1
- package/dist/core/store/sqlite-runtime.d.ts +15 -0
- package/dist/core/store/sqlite-runtime.js +2 -0
- package/dist/sdk/output/table-rows.d.ts +37 -0
- package/dist/sdk/output/table-rows.js +2 -0
- package/dist/sdk/output.d.ts +1 -0
- package/dist/sdk/output.js +2 -2
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/read-output-contracts.d.ts +3 -3
- package/dist/sdk/read-output-contracts.js +1 -1
- package/dist/sdk/test/workspace-snapshot.d.ts +1 -1
- package/dist/sdk/test/workspace-snapshot.js +1 -1
- package/docs/AGENT_OUTPUT_ENCODINGS.md +119 -0
- package/docs/PACKAGE_GATE_ACCEPTANCE.md +56 -0
- package/docs/README.md +2 -0
- package/docs/TESTING.md +11 -3
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/package.json +2 -2
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +2 -2
- package/plugins/pm-codex/plugin.json +1 -1
- package/runtime-dependencies.json +2 -2
|
@@ -103,9 +103,9 @@ export interface PmReadOutputReceipt {
|
|
|
103
103
|
command: PmReadOutputSurface;
|
|
104
104
|
/** Dimensions explicitly or compatibly requested by the invocation. */
|
|
105
105
|
requested_dimensions: PmReadOutputDimension[];
|
|
106
|
-
/** Layer
|
|
107
|
-
budget_source?: "default";
|
|
108
|
-
/**
|
|
106
|
+
/** Layer supplying a default ceiling or the context compatibility ceiling. */
|
|
107
|
+
budget_source?: "default" | "legacy";
|
|
108
|
+
/** Applied default or context compatibility ceiling; canonical/session budgets already disclose their value. */
|
|
109
109
|
budget_tokens?: number;
|
|
110
110
|
/** Deterministic precedence used during resolution. */
|
|
111
111
|
precedence: readonly ["canonical", "legacy", "intent", "default"];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="432f57fc-d487-5270-a86c-9a655f92eac7")}catch{}})();import{READ_OUTPUT_DIMENSION_FLAGS,READ_OUTPUT_COMPOSITION_FLAGS}from"./read-output/options.js";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,refreshReadOutputDeliveredCounts}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";import{READ_OUTPUT_INVOCATION_PROVENANCE}from"./read-output/provenance.js";const PM_READ_OUTPUT_DIMENSIONS=["include","amount","cost","encoding"],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"],READ_OUTPUT_PRECEDENCE=["canonical","legacy","intent","default"],CANONICAL_OPTIONS=READ_OUTPUT_DIMENSION_FLAGS,PM_READ_OUTPUT_OPTION_FLAGS=Object.freeze(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>CANONICAL_OPTIONS[dimension])),PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS=READ_OUTPUT_COMPOSITION_FLAGS,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:{}},VALUE_BEARING_INCLUDE_ALIASES=new Set(["--collapse","--fields","--section"]),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],dimensions=Object.freeze(Object.fromEntries(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>[dimension,Object.freeze({dimension,canonical_option:CANONICAL_OPTIONS[dimension],applicable:!0,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)),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()),root=normalizedCommand==="package catalog"||normalizedCommand==="packages catalog"||normalizedCommand==="package-catalog"||(normalizedCommand==="package"||normalizedCommand==="packages"||normalizedCommand==="extension")&&(options.catalog===!0||options.target==="catalog"||options.action==="catalog")?"package-catalog":normalizedCommand==="package manage"||normalizedCommand==="package-manage"?"package-manage":normalizedCommand.split(" ")[0],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"],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),!0),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]!==!1))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);return surface?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)])):new Map}function applyReadOutputIncludeModes(command,includeValue,commandOptions){const requested=stringList(includeValue)??[],modeOptions=readOutputIncludeModeOptions(command),selectors=[],modes=[],optionsWithProvenance=commandOptions,existingProvenance=optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE],canonicalModes=new Set(existingProvenance?.canonical_include_modes??[]),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("_","-")}`;isRequestedOption(readOption(commandOptions,legacyFlag))&&explicitLegacyAliases.add(legacyFlag),commandOptions[option]=!0,modes.push(token),canonicalModes.add(token)}const forwardedGetFieldSelectors=resolveReadOutputSurface(command)==="get"?selectors.filter(selector=>selector!=="item"):[],forwardedGetFields=forwardedGetFieldSelectors.length>0;return forwardedGetFields&&(commandOptions.fields=[...new Set([...stringList(commandOptions.fields)??[],...forwardedGetFieldSelectors])].join(","),canonicalModes.add("fields")),(modes.length>0||forwardedGetFields)&&(optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE]={canonical_include_modes:[...canonicalModes],explicit_legacy_aliases:[...explicitLegacyAliases],...existingProvenance?.cli_invocation_observed===!0?{cli_invocation_observed:!0}:{}}),{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,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===!1)return!0}function isRequestedOption(value){return value!==void 0&&value!==!1&&value!==null}function stringList(value){const normalized=(Array.isArray(value)?value:[value]).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),candidate={value,flag:alias.flag};if(isRequestedOption(value)&&usable(candidate))return candidate}}function resolveIncludeValue(canonical,legacy){const canonicalList=stringList(canonical);if(canonicalList)return{source:"canonical",value:canonicalList};if(legacy)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;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;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 legacy.flag==="--stream"||legacy.flag==="--follow"?{source:"legacy",value:"stream"}:legacy.value==="json"||legacy.value==="toon"?{source:"legacy",value:legacy.value}:void 0}function shouldIgnoreReadOutputLegacyAlias(provenance,dimension,flag){if(!provenance)return!1;const explicitLegacyAliases=new Set(provenance.explicit_legacy_aliases);if(provenance.cli_invocation_observed===!0||provenance.sdk_invocation_observed===!0)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){return command.trim().toLowerCase().replaceAll(/\s+/gu," ").split(" ")[0]==="list-all"||legacyByDimension.amount?.flag==="--no-truncate"||legacyByDimension.include?.flag==="--full"||provenance?.canonical_include_modes.includes("full")===!0}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;const contract=SURFACE_CONTRACT_BY_COMMAND.get(normalizedCommand),invocationProvenance=options[READ_OUTPUT_INVOCATION_PROVENANCE],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)},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))])),legacyAliasesUsed=PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>{const resolved=legacyByDimension[dimension];return resolved?[resolved.flag]:[]}),migrationHints=PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>{const resolved=legacyByDimension[dimension];return resolved?[contract.dimensions[dimension].legacy_aliases.find(entry=>entry.flag===resolved.flag).migration_hint]:[]}),encoding=resolveEncodingValue(options.outputFormat??options.output_format,legacyByDimension.encoding),include=resolveIncludeValue(options.outputInclude??options.output_include,legacyByDimension.include),amount=resolveAmountValue(options.outputLimit??options.output_limit,legacyByDimension.amount),explicitCost=resolveCostValue(options.outputBudget??options.output_budget,legacyByDimension.cost),completeResultIntent=hasCompleteReadOutputIntent(command,legacyByDimension,invocationProvenance),budget=resolvePmCommandOutputBudget(command,{generateFallback:!0}),resolvedOutputFormat=encoding?.value==="json"||options.resolvedOutputFormat==="json"?"json":"toon",cost=explicitCost??(completeResultIntent?{source:"intent",value:"unbounded"}:{source:"default",value:budget.default_max_estimated_tokens_by_format[resolvedOutputFormat]});return{command:normalizedCommand,include,amount,cost,encoding,canonical_options_used:canonicalReadOutputOptionsUsed({include,amount,cost,encoding},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"]),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:{},itemFields=[...new Set([...Object.keys(item),...GET_STABLE_DERIVED_ITEM_SELECTORS.filter(key=>Object.hasOwn(item,key))])].sort((left,right)=>left.localeCompare(right)),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),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"),itemSelectors=selectors.flatMap(selector=>selector.startsWith("item.")?[selector.slice(5)]: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))),projected=Object.fromEntries(Object.entries(result).filter(([key])=>ENVELOPE_KEYS.has(key)||selectedSections.has(key)));fullItem?projected.item=vocabulary.item: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}`}))],combinedOmittedFieldGroups=[...isRecord(projected.omission_receipt)&&Array.isArray(projected.omission_receipt.omitted_field_groups)?projected.omission_receipt.omitted_field_groups:[],...omittedFieldGroups];return projected.omission_receipt={has_omissions:combinedOmittedFieldGroups.length>0,omitted_field_group_count:combinedOmittedFieldGroups.length,omitted_field_groups:combinedOmittedFieldGroups},projected}function countPopulatedRows(result){let populated=0;return mapReadOutputRows({...result},entry=>(isRecord(entry)&&Object.keys(entry).length>0&&(populated+=1),entry)),populated}function rejectEmptyIncludeProjection(command,original,shaped,selectors){if(countPopulatedRows(original)===0||countPopulatedRows(shaped)>0)return;const modes=[...readOutputIncludeModeOptions(command).keys()],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),qualifiedRowSelectors=selectors.flatMap(selector=>rows.flatMap(rowPath=>selector.startsWith(`${rowPath}.`)?[selector.slice(rowPath.length+1)]:[])),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},rowSelectors=qualifiedRowSelectors.length>0?qualifiedRowSelectors:selectors,shaped=mapReadOutputRows(projected,entry=>isRecord(entry)?projectRecordFields(entry,rowSelectors):entry);return rejectEmptyIncludeProjection(command,result,shaped,rowSelectors),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;if(bounded.has_more=!0,bounded.truncated=!0,typeof bounded.count=="number"){const activeRowKey=isRecord(bounded.projection)?bounded.projection.row_key:void 0;bounded.count=typeof activeRowKey=="string"&&Array.isArray(bounded[activeRowKey])?bounded[activeRowKey].length:countReadOutputRows(bounded)}return bounded.applied_bound={kind:"output_limit",source:"explicit",value:amount},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,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),receipt=result.read_output,session=parseReadOutputSession(options.outputSession??options.output_session);return session===void 0?(updateReadOutputReceiptEstimate(result,receipt,format),result):attachReadOutputSessionContracts(result,session,receipt,format)}function attachValidateDiagnosticRowContract(command,result){if(command!=="validate")return result;const projection=isRecord(result.projection)?result.projection:void 0;if(!(Array.isArray(projection?.declared_field_groups)?projection.declared_field_groups:[]).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)))],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:{},existingRowKeys=Array.isArray(existingContract.row_keys)?existingContract.row_keys.filter(entry=>typeof entry=="string"):[],existingContinuationRowKeys=Array.isArray(existingContract.continuation_row_keys)?existingContract.continuation_row_keys.filter(entry=>typeof entry=="string"):[],rowKeys=existingRowKeys.length>0?existingRowKeys:diagnosticRowKeys,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,options){let projected={...result};if(resolved.include?.source==="canonical"&&(projected=applyIncludeProjection(resolved.command,projected,resolved.include.value)),resolved.command==="assurance"&&(projected=prioritizeAssuranceAssertions(projected)),refreshReadOutputDeliveredCounts(projected,result),projected=applyReadOutputContinuation(projected,resolved.command,cursor),resolved.command==="history"&&cursor){const historyRowKeys=["compact_history","provenance_history","history","diff"];if(projected=Object.fromEntries(Object.entries(projected).filter(([key])=>!historyRowKeys.includes(key)||key===cursor.path)),isRecord(projected.projection)&&(projected.projection={...projected.projection,row_key:cursor.path}),isRecord(projected.row_contract)){const rowContract=projected.row_contract;projected.row_contract={...rowContract,row_keys:[cursor.path],...Array.isArray(rowContract.continuation_row_keys)?{continuation_row_keys:[cursor.path]}:{}}}projected.count=Object.keys(projected[cursor.path]).length}const continuationSource=result.count_only===!0?{...projected,count_only:!0,count:result.count}:projected,continuationState=captureReadOutputContinuationState(projected,result,resolved.command,cursor,options);return resolved.amount?.source==="canonical"&&(projected=applyAmountBound(projected,resolved.amount.value),continuationState.cursorContinuesExistingPage&&rebaseCompactedProducerCursor(projected,continuationState.originalItems,continuationState.cursorSource,!0,continuationState.originalItemOffset)),refreshReadOutputDeliveredCounts(projected,continuationSource),{projected:session===void 0?projected:applyReadOutputSessionReferences(projected,session),continuationState}}function resolveBindingReadOutputBudget(resolved,session){return[...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)}]].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:!1,strings_compacted:!1,rows_compacted:!1,result_omitted:!0,...session===void 0?{omitted_result_estimated_tokens:omittedResultEstimatedTokens}:{}},omitted={output_budget_exceeded:{omitted_result:!0,reason:"requested_budget_infeasible",restore_with:"Unbounded",recovery:{outputBudget:"unbounded"}},read_output:minimalReceipt},boundedOmission=session===void 0?omitted:attachReadOutputSessionContracts(omitted,session,minimalReceipt,format);if(session===void 0&&updateReadOutputReceiptEstimate(boundedOmission,minimalReceipt,format),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===!0||options.output_row_contract===!0||resolved.canonical_options_used.includes("--output-include")||resolved.command==="list"&&resolved.canonical_options_used.length>0&&resolved.include?.value.includes("full")===!0}function canReturnReadOutputUnchanged(resolved,session,result,format,options){if(session!==void 0||requiresReadOutputAudit(resolved,options))return!1;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!1}return resolved.cost===void 0||resolved.cost.value==="unbounded"||resolved.cost.source==="legacy"||estimateReadOutputTokens(options.outputRowContract===!1?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"]:[],afterByPath=new Map(readOutputContinuationRowCollections(projected).map(collection=>[collection.path,Array.isArray(collection.value)?collection.value.length:Object.keys(collection.value).length])),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}]}),primary=continuations[0],continuationHint=primary?"; page --output-cursor":"",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});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 rebaseCompactedProducerCursor(projected,originalItems,cursorSource,cursorContinuesExistingPage,originalItemOffset){if(typeof cursorSource!="string"||!Array.isArray(projected.items))return!1;const retainedCount=projected.items.length,originalItemCount=originalItems.length;if(retainedCount===0||retainedCount>=originalItemCount)return!1;let cursor;try{cursor=decodeQueryCursorEnvelope(cursorSource)}catch{return!1}const sourceIndex=cursor.after_index;if(sourceIndex===void 0)return!1;const last=originalItems[retainedCount-1];if(Object.prototype.toString.call(last)!=="[object Object]")return!1;const lastId=Reflect.get(last,"id");if(typeof lastId!="string"||lastId.length===0)return!1;const afterIndex=cursorContinuesExistingPage?sourceIndex-(originalItemCount-retainedCount):sourceIndex+originalItemOffset+retainedCount;return afterIndex<0?!1:(projected.next_cursor=encodeQueryCursor(cursor.fingerprint,lastId,afterIndex,cursor.snapshot),!0)}function captureReadOutputContinuationState(projected,source,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,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)}]})),cursorContinuesExistingPage=typeof projected.next_cursor=="string",originalItemOffset=cursor?.path==="items"?cursor.offset:0;return{collectionsBeforeBudget,originalItems:Array.isArray(source.items)?originalItemOffset>0?source.items.slice(originalItemOffset):source.items:[],originalItemOffset,cursorContinuesExistingPage,cursorSource:cursorContinuesExistingPage?projected.next_cursor:options.after}}function compactReadOutputProjection(projected,source,countOnly,resolved,receipt,bindingBudget,session,continuationState,measuredResultTokens,format){const deliveredSource={...source,count_only:countOnly},assuranceMinimumRows=resolved.command==="assurance"&&Array.isArray(projected.assertions)?projected.assertions.filter(row=>isRecord(row)&&row.verdict!=="pass").length:0,minimumRowsByPath=new Map;if(assuranceMinimumRows>0&&minimumRowsByPath.set("assertions",assuranceMinimumRows),resolved.command==="history"&&Array.isArray(projected.diff))for(const collection of readOutputBudgetCollections(projected))collection.path.startsWith("diff.")&&minimumRowsByPath.set(collection.path,Object.keys(collection.value).length);return compactReadOutputToBudget(projected,receipt,bindingBudget.tokens,minimumRowsByPath,format,compacted=>{refreshReadOutputDeliveredCounts(compacted,deliveredSource);const continuationCursorRebased=rebaseCompactedProducerCursor(compacted,continuationState.originalItems,continuationState.cursorSource,continuationState.cursorContinuesExistingPage,continuationState.originalItemOffset);if(attachReadOutputTruncationDisclosure(compacted,resolved,receipt,bindingBudget,continuationCursorRebased,measuredResultTokens,continuationState.collectionsBeforeBudget),resolved.command==="history"&&isRecord(compacted.projection)){compacted.has_more=typeof compacted.next_cursor=="string"||compacted.applied_bound?.kind==="output_limit";const rowKey=compacted.projection.row_key;typeof rowKey=="string"&&Array.isArray(compacted[rowKey])&&(compacted.count=compacted[rowKey].length)}session!==void 0&&Object.assign(compacted,attachReadOutputSessionContracts(compacted,session,receipt,format))},resolved.command==="history"&&Array.isArray(projected.diff))}function applyReadOutputDimensions(command,options,result){const resolved=resolveReadOutputDimensions(command,options);if(!resolved)return result;const format=readOutputMeasurementFormat(options),session=parseReadOutputSession(options.outputSession??options.output_session),rawCursor=options.outputCursor??options.output_cursor,cursor=typeof rawCursor=="string"?decodeReadOutputContinuationCursor(rawCursor):void 0,requested=requestedDimensions(resolved),continuationReadyResult=attachValidateDiagnosticRowContract(resolved.command,result);if(cursor===void 0&&canReturnReadOutputUnchanged(resolved,session,continuationReadyResult,format,options))return continuationReadyResult;const bindingBudget=resolveBindingReadOutputBudget(resolved,session),projection=projectReadOutputRows(continuationReadyResult,resolved,session,cursor,options);let projected=projection.projected;preserveReadOutputRowContract(projected,projected,options.outputRowContract===!1);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:!0,strings_compacted:!1,rows_compacted:!1,result_omitted:!1};if(projected.read_output=receipt,projected=session===void 0?projected:attachReadOutputSessionContracts(projected,session,receipt,format),updateReadOutputReceiptEstimate(projected,receipt,format),bindingBudget!==void 0&&receipt.estimated_tokens>bindingBudget.tokens){const brief=projectReadOutputItemToBrief(resolved.command,options,projected);brief!==void 0&&(receipt.applied_depth="brief",receipt.degradation_reason="output_budget_reached",preserveReadOutputRowContract(projected,brief),projected=stabilizeReadOutputReceiptEstimates(brief,options)),receipt.estimated_tokens>bindingBudget.tokens&&(projected=compactReadOutputProjection(projected,projected,continuationReadyResult.count_only===!0,resolved,receipt,bindingBudget,session,projection.continuationState,receipt.estimated_tokens,format))}return bindingBudget!==void 0&&receipt.estimated_tokens>bindingBudget.tokens?omitReadOutputForBudget(resolved,requested,session,bindingBudget,receipt.estimated_tokens,format):projected}function isReadOutputBudgetExceeded(result){return isRecord(result)&&isRecord(result.output_budget_exceeded)&&result.output_budget_exceeded.omitted_result===!0&&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};
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7d98b4ee-f8a8-5207-a914-4cf80da27241")}catch{}})();import{READ_OUTPUT_DIMENSION_FLAGS,READ_OUTPUT_COMPOSITION_FLAGS}from"./read-output/options.js";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,refreshReadOutputDeliveredCounts}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";import{READ_OUTPUT_INVOCATION_PROVENANCE}from"./read-output/provenance.js";const PM_READ_OUTPUT_DIMENSIONS=["include","amount","cost","encoding"],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"],READ_OUTPUT_PRECEDENCE=["canonical","legacy","intent","default"],CANONICAL_OPTIONS=READ_OUTPUT_DIMENSION_FLAGS,PM_READ_OUTPUT_OPTION_FLAGS=Object.freeze(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>CANONICAL_OPTIONS[dimension])),PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS=READ_OUTPUT_COMPOSITION_FLAGS,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:{}},VALUE_BEARING_INCLUDE_ALIASES=new Set(["--collapse","--fields","--section"]),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],dimensions=Object.freeze(Object.fromEntries(PM_READ_OUTPUT_DIMENSIONS.map(dimension=>[dimension,Object.freeze({dimension,canonical_option:CANONICAL_OPTIONS[dimension],applicable:!0,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)),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()),root=normalizedCommand==="package catalog"||normalizedCommand==="packages catalog"||normalizedCommand==="package-catalog"||(normalizedCommand==="package"||normalizedCommand==="packages"||normalizedCommand==="extension")&&(options.catalog===!0||options.target==="catalog"||options.action==="catalog")?"package-catalog":normalizedCommand==="package manage"||normalizedCommand==="package-manage"?"package-manage":normalizedCommand.split(" ")[0],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"],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),!0),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]!==!1))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);return surface?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)])):new Map}function applyReadOutputIncludeModes(command,includeValue,commandOptions){const requested=stringList(includeValue)??[],modeOptions=readOutputIncludeModeOptions(command),selectors=[],modes=[],optionsWithProvenance=commandOptions,existingProvenance=optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE],canonicalModes=new Set(existingProvenance?.canonical_include_modes??[]),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("_","-")}`;isRequestedOption(readOption(commandOptions,legacyFlag))&&explicitLegacyAliases.add(legacyFlag),commandOptions[option]=!0,modes.push(token),canonicalModes.add(token)}const forwardedGetFieldSelectors=resolveReadOutputSurface(command)==="get"?selectors.filter(selector=>selector!=="item"):[],forwardedGetFields=forwardedGetFieldSelectors.length>0;return forwardedGetFields&&(commandOptions.fields=[...new Set([...stringList(commandOptions.fields)??[],...forwardedGetFieldSelectors])].join(","),canonicalModes.add("fields")),(modes.length>0||forwardedGetFields)&&(optionsWithProvenance[READ_OUTPUT_INVOCATION_PROVENANCE]={canonical_include_modes:[...canonicalModes],explicit_legacy_aliases:[...explicitLegacyAliases],...existingProvenance?.cli_invocation_observed===!0?{cli_invocation_observed:!0}:{}}),{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,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===!1)return!0}function isRequestedOption(value){return value!==void 0&&value!==!1&&value!==null}function stringList(value){const normalized=(Array.isArray(value)?value:[value]).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),candidate={value,flag:alias.flag};if(isRequestedOption(value)&&usable(candidate))return candidate}}function resolveIncludeValue(canonical,legacy){const canonicalList=stringList(canonical);if(canonicalList)return{source:"canonical",value:canonicalList};if(legacy)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;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;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 legacy.flag==="--stream"||legacy.flag==="--follow"?{source:"legacy",value:"stream"}:legacy.value==="json"||legacy.value==="toon"?{source:"legacy",value:legacy.value}:void 0}function shouldIgnoreReadOutputLegacyAlias(provenance,dimension,flag){if(!provenance)return!1;const explicitLegacyAliases=new Set(provenance.explicit_legacy_aliases);if(provenance.cli_invocation_observed===!0||provenance.sdk_invocation_observed===!0)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){return command.trim().toLowerCase().replaceAll(/\s+/gu," ").split(" ")[0]==="list-all"||legacyByDimension.amount?.flag==="--no-truncate"||legacyByDimension.include?.flag==="--full"||provenance?.canonical_include_modes.includes("full")===!0}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;const contract=SURFACE_CONTRACT_BY_COMMAND.get(normalizedCommand),invocationProvenance=options[READ_OUTPUT_INVOCATION_PROVENANCE],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)},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))])),legacyAliasesUsed=PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>{const resolved=legacyByDimension[dimension];return resolved?[resolved.flag]:[]}),migrationHints=PM_READ_OUTPUT_DIMENSIONS.flatMap(dimension=>{const resolved=legacyByDimension[dimension];return resolved?[contract.dimensions[dimension].legacy_aliases.find(entry=>entry.flag===resolved.flag).migration_hint]:[]}),encoding=resolveEncodingValue(options.outputFormat??options.output_format,legacyByDimension.encoding),include=resolveIncludeValue(options.outputInclude??options.output_include,legacyByDimension.include),amount=resolveAmountValue(options.outputLimit??options.output_limit,legacyByDimension.amount),explicitCost=resolveCostValue(options.outputBudget??options.output_budget,legacyByDimension.cost),completeResultIntent=hasCompleteReadOutputIntent(command,legacyByDimension,invocationProvenance),budget=resolvePmCommandOutputBudget(command,{generateFallback:!0}),resolvedOutputFormat=encoding?.value==="json"||options.resolvedOutputFormat==="json"?"json":"toon",cost=explicitCost??(completeResultIntent?{source:"intent",value:"unbounded"}:{source:"default",value:budget.default_max_estimated_tokens_by_format[resolvedOutputFormat]});return{command:normalizedCommand,include,amount,cost,encoding,canonical_options_used:canonicalReadOutputOptionsUsed({include,amount,cost,encoding},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"]),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:{},itemFields=[...new Set([...Object.keys(item),...GET_STABLE_DERIVED_ITEM_SELECTORS.filter(key=>Object.hasOwn(item,key))])].sort((left,right)=>left.localeCompare(right)),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),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"),itemSelectors=selectors.flatMap(selector=>selector.startsWith("item.")?[selector.slice(5)]: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))),projected=Object.fromEntries(Object.entries(result).filter(([key])=>ENVELOPE_KEYS.has(key)||selectedSections.has(key)));fullItem?projected.item=vocabulary.item: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}`}))],combinedOmittedFieldGroups=[...isRecord(projected.omission_receipt)&&Array.isArray(projected.omission_receipt.omitted_field_groups)?projected.omission_receipt.omitted_field_groups:[],...omittedFieldGroups];return projected.omission_receipt={has_omissions:combinedOmittedFieldGroups.length>0,omitted_field_group_count:combinedOmittedFieldGroups.length,omitted_field_groups:combinedOmittedFieldGroups},projected}function countPopulatedRows(result){let populated=0;return mapReadOutputRows({...result},entry=>(isRecord(entry)&&Object.keys(entry).length>0&&(populated+=1),entry)),populated}function rejectEmptyIncludeProjection(command,original,shaped,selectors){if(countPopulatedRows(original)===0||countPopulatedRows(shaped)>0)return;const modes=[...readOutputIncludeModeOptions(command).keys()],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),qualifiedRowSelectors=selectors.flatMap(selector=>rows.flatMap(rowPath=>selector.startsWith(`${rowPath}.`)?[selector.slice(rowPath.length+1)]:[])),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},rowSelectors=qualifiedRowSelectors.length>0?qualifiedRowSelectors:selectors,shaped=mapReadOutputRows(projected,entry=>isRecord(entry)?projectRecordFields(entry,rowSelectors):entry);return rejectEmptyIncludeProjection(command,result,shaped,rowSelectors),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;if(bounded.has_more=!0,bounded.truncated=!0,typeof bounded.count=="number"){const activeRowKey=isRecord(bounded.projection)?bounded.projection.row_key:void 0;bounded.count=typeof activeRowKey=="string"&&Array.isArray(bounded[activeRowKey])?bounded[activeRowKey].length:countReadOutputRows(bounded)}return bounded.applied_bound={kind:"output_limit",source:"explicit",value:amount},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,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),receipt=result.read_output,session=parseReadOutputSession(options.outputSession??options.output_session);return session===void 0?(updateReadOutputReceiptEstimate(result,receipt,format),result):attachReadOutputSessionContracts(result,session,receipt,format)}function attachValidateDiagnosticRowContract(command,result){if(command!=="validate")return result;const projection=isRecord(result.projection)?result.projection:void 0;if(!(Array.isArray(projection?.declared_field_groups)?projection.declared_field_groups:[]).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)))],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:{},existingRowKeys=Array.isArray(existingContract.row_keys)?existingContract.row_keys.filter(entry=>typeof entry=="string"):[],existingContinuationRowKeys=Array.isArray(existingContract.continuation_row_keys)?existingContract.continuation_row_keys.filter(entry=>typeof entry=="string"):[],rowKeys=existingRowKeys.length>0?existingRowKeys:diagnosticRowKeys,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,options){let projected={...result};if(resolved.include?.source==="canonical"&&(projected=applyIncludeProjection(resolved.command,projected,resolved.include.value)),resolved.command==="assurance"&&(projected=prioritizeAssuranceAssertions(projected)),refreshReadOutputDeliveredCounts(projected,result),projected=applyReadOutputContinuation(projected,resolved.command,cursor),resolved.command==="history"&&cursor){const historyRowKeys=["compact_history","provenance_history","history","diff"];if(projected=Object.fromEntries(Object.entries(projected).filter(([key])=>!historyRowKeys.includes(key)||key===cursor.path)),isRecord(projected.projection)&&(projected.projection={...projected.projection,row_key:cursor.path}),isRecord(projected.row_contract)){const rowContract=projected.row_contract;projected.row_contract={...rowContract,row_keys:[cursor.path],...Array.isArray(rowContract.continuation_row_keys)?{continuation_row_keys:[cursor.path]}:{}}}projected.count=Object.keys(projected[cursor.path]).length}const continuationSource=result.count_only===!0?{...projected,count_only:!0,count:result.count}:projected,continuationState=captureReadOutputContinuationState(projected,result,resolved.command,cursor,options);return resolved.amount?.source==="canonical"&&(projected=applyAmountBound(projected,resolved.amount.value),continuationState.cursorContinuesExistingPage&&rebaseCompactedProducerCursor(projected,continuationState.originalItems,continuationState.cursorSource,!0,continuationState.originalItemOffset)),refreshReadOutputDeliveredCounts(projected,continuationSource),{projected:session===void 0?projected:applyReadOutputSessionReferences(projected,session),continuationState}}function resolveBindingReadOutputBudget(resolved,session){return[...resolved.cost!==void 0&&resolved.cost.value!=="unbounded"&&(resolved.cost.source==="canonical"||resolved.cost.source==="default"||resolved.command==="context"&&resolved.cost.source==="legacy")?[{source:resolved.cost.source,tokens:resolved.cost.value}]:[],...session===void 0?[]:[{source:"session",tokens:readOutputSessionRemainingTokens(session)}]].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 hasContextIntentBudgetReceipt(result,tokens){return isRecord(result.context_intent)&&result.context_intent.command==="context"&&result.context_intent.token_budget===tokens&&result.context_intent.within_budget===!0}function readOutputBudgetReceiptFields(budget,result={}){return budget?.source==="default"||budget?.source==="legacy"&&!hasContextIntentBudgetReceipt(result,budget.tokens)?{budget_source:budget.source,budget_tokens:budget.tokens}:{}}function omitReadOutputForBudget(resolved,requested,session,bindingBudget,omittedResultEstimatedTokens,format){const minimalReceipt={contract_version:1,command:resolved.command,requested_dimensions:requested,...readOutputBudgetReceiptFields(bindingBudget),precedence:resolved.precedence,...canonicalReadOutputReceiptFields(resolved),legacy_aliases_used:[],migration_hints:[],estimated_tokens:0,within_budget:!1,strings_compacted:!1,rows_compacted:!1,result_omitted:!0,...session===void 0?{omitted_result_estimated_tokens:omittedResultEstimatedTokens}:{}},omitted={output_budget_exceeded:{omitted_result:!0,reason:"requested_budget_infeasible",restore_with:"Unbounded",recovery:{outputBudget:"unbounded"}},read_output:minimalReceipt},boundedOmission=session===void 0?omitted:attachReadOutputSessionContracts(omitted,session,minimalReceipt,format);if(session===void 0&&updateReadOutputReceiptEstimate(boundedOmission,minimalReceipt,format),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,result){return resolved.command==="context"&&resolved.cost?.source==="legacy"&&!hasContextIntentBudgetReceipt(result,resolved.cost.value)||options.outputRowContract===!0||options.output_row_contract===!0||resolved.canonical_options_used.includes("--output-include")||resolved.command==="list"&&resolved.canonical_options_used.length>0&&resolved.include?.value.includes("full")===!0}function canReturnReadOutputUnchanged(resolved,session,result,format,options){if(session!==void 0||requiresReadOutputAudit(resolved,options,result))return!1;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!1}return resolved.cost===void 0||resolved.cost.value==="unbounded"||resolved.cost.source==="legacy"&&resolved.command!=="context"||estimateReadOutputTokens(options.outputRowContract===!1?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"]:[],afterByPath=new Map(readOutputContinuationRowCollections(projected).map(collection=>[collection.path,Array.isArray(collection.value)?collection.value.length:Object.keys(collection.value).length])),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}]}),primary=continuations[0],continuationHint=primary?"; page --output-cursor":"",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});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 rebaseCompactedProducerCursor(projected,originalItems,cursorSource,cursorContinuesExistingPage,originalItemOffset){if(typeof cursorSource!="string"||!Array.isArray(projected.items))return!1;const retainedCount=projected.items.length,originalItemCount=originalItems.length;if(retainedCount===0||retainedCount>=originalItemCount)return!1;let cursor;try{cursor=decodeQueryCursorEnvelope(cursorSource)}catch{return!1}const sourceIndex=cursor.after_index;if(sourceIndex===void 0)return!1;const last=originalItems[retainedCount-1];if(Object.prototype.toString.call(last)!=="[object Object]")return!1;const lastId=Reflect.get(last,"id");if(typeof lastId!="string"||lastId.length===0)return!1;const afterIndex=cursorContinuesExistingPage?sourceIndex-(originalItemCount-retainedCount):sourceIndex+originalItemOffset+retainedCount;return afterIndex<0?!1:(projected.next_cursor=encodeQueryCursor(cursor.fingerprint,lastId,afterIndex,cursor.snapshot),!0)}function captureReadOutputContinuationState(projected,source,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,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)}]})),cursorContinuesExistingPage=typeof projected.next_cursor=="string",originalItemOffset=cursor?.path==="items"?cursor.offset:0;return{collectionsBeforeBudget,originalItems:Array.isArray(source.items)?originalItemOffset>0?source.items.slice(originalItemOffset):source.items:[],originalItemOffset,cursorContinuesExistingPage,cursorSource:cursorContinuesExistingPage?projected.next_cursor:options.after}}function compactReadOutputProjection(projected,source,countOnly,resolved,receipt,bindingBudget,session,continuationState,measuredResultTokens,format){const deliveredSource={...source,count_only:countOnly},assuranceMinimumRows=resolved.command==="assurance"&&Array.isArray(projected.assertions)?projected.assertions.filter(row=>isRecord(row)&&row.verdict!=="pass").length:0,minimumRowsByPath=new Map;if(assuranceMinimumRows>0&&minimumRowsByPath.set("assertions",assuranceMinimumRows),resolved.command==="history"&&Array.isArray(projected.diff))for(const collection of readOutputBudgetCollections(projected))collection.path.startsWith("diff.")&&minimumRowsByPath.set(collection.path,Object.keys(collection.value).length);return compactReadOutputToBudget(projected,receipt,bindingBudget.tokens,minimumRowsByPath,format,compacted=>{refreshReadOutputDeliveredCounts(compacted,deliveredSource);const continuationCursorRebased=rebaseCompactedProducerCursor(compacted,continuationState.originalItems,continuationState.cursorSource,continuationState.cursorContinuesExistingPage,continuationState.originalItemOffset);if(attachReadOutputTruncationDisclosure(compacted,resolved,receipt,bindingBudget,continuationCursorRebased,measuredResultTokens,continuationState.collectionsBeforeBudget),resolved.command==="history"&&isRecord(compacted.projection)){compacted.has_more=typeof compacted.next_cursor=="string"||compacted.applied_bound?.kind==="output_limit";const rowKey=compacted.projection.row_key;typeof rowKey=="string"&&Array.isArray(compacted[rowKey])&&(compacted.count=compacted[rowKey].length)}session!==void 0&&Object.assign(compacted,attachReadOutputSessionContracts(compacted,session,receipt,format))},resolved.command==="history"&&Array.isArray(projected.diff))}function applyReadOutputDimensions(command,options,result){const resolved=resolveReadOutputDimensions(command,options);if(!resolved)return result;const format=readOutputMeasurementFormat(options),session=parseReadOutputSession(options.outputSession??options.output_session),rawCursor=options.outputCursor??options.output_cursor,cursor=typeof rawCursor=="string"?decodeReadOutputContinuationCursor(rawCursor):void 0,requested=requestedDimensions(resolved),continuationReadyResult=attachValidateDiagnosticRowContract(resolved.command,result);if(cursor===void 0&&canReturnReadOutputUnchanged(resolved,session,continuationReadyResult,format,options))return continuationReadyResult;const bindingBudget=resolveBindingReadOutputBudget(resolved,session),projection=projectReadOutputRows(continuationReadyResult,resolved,session,cursor,options);let projected=projection.projected;preserveReadOutputRowContract(projected,projected,options.outputRowContract===!1);const receipt={contract_version:1,command:resolved.command,requested_dimensions:requested,...readOutputBudgetReceiptFields(bindingBudget,projected),precedence:resolved.precedence,...canonicalReadOutputReceiptFields(resolved),legacy_aliases_used:resolved.legacy_aliases_used,migration_hints:resolved.migration_hints,estimated_tokens:0,within_budget:!0,strings_compacted:!1,rows_compacted:!1,result_omitted:!1};if(projected.read_output=receipt,projected=session===void 0?projected:attachReadOutputSessionContracts(projected,session,receipt,format),updateReadOutputReceiptEstimate(projected,receipt,format),bindingBudget!==void 0&&receipt.estimated_tokens>bindingBudget.tokens){const brief=projectReadOutputItemToBrief(resolved.command,options,projected);brief!==void 0&&(receipt.applied_depth="brief",receipt.degradation_reason="output_budget_reached",preserveReadOutputRowContract(projected,brief),projected=stabilizeReadOutputReceiptEstimates(brief,options)),receipt.estimated_tokens>bindingBudget.tokens&&(projected=compactReadOutputProjection(projected,projected,continuationReadyResult.count_only===!0,resolved,receipt,bindingBudget,session,projection.continuationState,receipt.estimated_tokens,format))}return bindingBudget!==void 0&&receipt.estimated_tokens>bindingBudget.tokens?omitReadOutputForBudget(resolved,requested,session,bindingBudget,receipt.estimated_tokens,format):projected}function isReadOutputBudgetExceeded(result){return isRecord(result)&&isRecord(result.output_budget_exceeded)&&result.output_budget_exceeded.omitted_result===!0&&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,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copy source files into a disposable workspace and link root and nested
|
|
2
|
+
* Copy source files and independent Git identity into a disposable workspace and link root and nested
|
|
3
3
|
* dependency directories at their original relative paths. Dependency trees
|
|
4
4
|
* are shared by convention, not protected against writes; callers must trust
|
|
5
5
|
* the linked command and use an independent install for dependency mutations.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="26cfff37-1b7e-556f-8656-2e5c7c9d616f")}catch{}})();import{cp,lstat,mkdir,readlink,realpath,stat,symlink}from"node:fs/promises";import{execFile}from"node:child_process";import path from"node:path";import{promisify}from"node:util";import{isFileMissingError}from"../../core/fs/fs-utils.js";const EXCLUDED_SEGMENTS=new Set([".agents",".git",".nyc_output",".turbo","coverage"]),execFileAsync=promisify(execFile);async function seedSnapshotGitIdentity(sourceRoot,snapshotRoot){const marker=await statSnapshotTarget(path.join(sourceRoot,".git"));if(!marker||marker.isDirectory()&&!await statSnapshotTarget(path.join(sourceRoot,".git/HEAD")))return;const env=Object.fromEntries(Object.entries(process.env).filter(([key])=>!key.toUpperCase().startsWith("GIT_")));await execFileAsync("git",["clone","--no-local","--no-checkout","--template=","--origin=origin","--",sourceRoot,snapshotRoot],{env,timeout:12e4,maxBuffer:1024*1024,windowsHide:!0}),await execFileAsync("git",["-C",snapshotRoot,"remote","remove","origin"],{env,timeout:1e4,windowsHide:!0})}function hasExcludedSegment(relative){return relative.split(path.sep).some(segment=>EXCLUDED_SEGMENTS.has(segment.toLowerCase()))}function isOutsideWorkspace(relative){return relative===".."||relative.startsWith(`..${path.sep}`)||path.isAbsolute(relative)}async function statSnapshotTarget(source){try{return await stat(source)}catch(error){if(!isFileMissingError(error))throw error;return}}async function resolveLinkTarget(target){const missing=[];let ancestor=target;for(;path.dirname(ancestor)!==ancestor;)try{return path.join(await realpath(ancestor),...missing)}catch(error){if(!isFileMissingError(error))throw error;missing.unshift(path.basename(ancestor)),ancestor=path.dirname(ancestor)}return path.join(await realpath(ancestor),...missing)}async function resolveSnapshotTarget(target,sourceRoot,dependencyRoots){const relative=path.relative(sourceRoot,await resolveLinkTarget(target));if(!isOutsideWorkspace(relative))return relative;const suffix=[];let ancestor=target;for(;path.dirname(ancestor)!==ancestor;){const physicalAncestor=await resolveLinkTarget(ancestor),dependency=dependencyRoots.find(([,root])=>root===physicalAncestor);if(dependency)return path.join(dependency[0],...suffix);suffix.unshift(path.basename(ancestor)),ancestor=path.dirname(ancestor)}return relative}async function seedLinkedTestWorkspaceSnapshot(sourceRoot,snapshotRoot){const dependencyRoots=[],sourceLinks=[],resolvedSourceRoot=await realpath(sourceRoot),resolvedSnapshotRoot=await resolveLinkTarget(path.resolve(snapshotRoot));if(![path.relative(resolvedSourceRoot,resolvedSnapshotRoot),path.relative(resolvedSnapshotRoot,resolvedSourceRoot)].every(isOutsideWorkspace))throw new Error("Snapshot destination must be disjoint from the source workspace; choose a temporary root outside the checkout.");await mkdir(path.dirname(snapshotRoot),{recursive:!0}),await seedSnapshotGitIdentity(resolvedSourceRoot,snapshotRoot),await cp(resolvedSourceRoot,snapshotRoot,{recursive:!0,force:!0,async filter(source){const relative=path.relative(resolvedSourceRoot,source);if(!relative)return!0;if(hasExcludedSegment(relative))return!1;if(path.basename(source).toLowerCase()==="node_modules"){if((await statSnapshotTarget(source))?.isDirectory()){const target=await resolveLinkTarget(source),targetRelative=path.relative(resolvedSourceRoot,target);if(!isOutsideWorkspace(path.relative(target,resolvedSourceRoot))||!isOutsideWorkspace(targetRelative)&&(hasExcludedSegment(targetRelative)||!targetRelative.split(path.sep).some(segment=>segment.toLowerCase()==="node_modules")))throw new Error(`Dependency symlink must target an included dependency directory or external installation: ${relative}`);dependencyRoots.push([relative,target])}return!1}return(await lstat(source)).isSymbolicLink()?(sourceLinks.push([relative,path.resolve(path.dirname(source),await readlink(source)),(await statSnapshotTarget(source))?.isDirectory()?"junction":"file"]),!1):!0}});for(const[relative]of dependencyRoots)await symlink(path.resolve(resolvedSourceRoot,relative),path.join(snapshotRoot,relative),"junction");for(const[relative,target,type]of sourceLinks){const targetRelative=await resolveSnapshotTarget(target,resolvedSourceRoot,dependencyRoots);if(isOutsideWorkspace(targetRelative)||hasExcludedSegment(targetRelative))throw new Error(`Source symlink must target included workspace source: ${relative}`);await symlink(path.resolve(snapshotRoot,targetRelative),path.join(snapshotRoot,relative),type)}}export{seedLinkedTestWorkspaceSnapshot};
|
|
2
2
|
//# sourceMappingURL=workspace-snapshot.js.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Fact-preserving agent output
|
|
2
|
+
|
|
3
|
+
Tracked by [pm-kvxqp1](../.agents/pm/features/pm-kvxqp1.toon) and
|
|
4
|
+
[pm-5t33or](../.agents/pm/features/pm-5t33or.toon). Project management is context
|
|
5
|
+
management: fewer tokens must carry the same decision facts.
|
|
6
|
+
|
|
7
|
+
## Presentation contract
|
|
8
|
+
|
|
9
|
+
JSON remains the authoritative structured result, including stable collection
|
|
10
|
+
counts, aliases, projections, omission receipts, and continuation coordinates.
|
|
11
|
+
TOON keeps the existing sparse presentation policy. It renders primitive arrays
|
|
12
|
+
inline and uses standard nested TOON for short object collections. For collections
|
|
13
|
+
of at least two object rows, the renderer compares the complete nested and
|
|
14
|
+
key-hoisted representations, including decoding metadata, and selects the table
|
|
15
|
+
only when its UTF-8 payload is smaller. Before constructing a candidate, it counts
|
|
16
|
+
present own-field cells and distinct columns in linear input time. A dense grid
|
|
17
|
+
larger than twice the present-cell count uses expanded TOON without allocating
|
|
18
|
+
padding or absent coordinates. Uniform collections remain eligible at any size.
|
|
19
|
+
Existing flat tables remain unchanged.
|
|
20
|
+
|
|
21
|
+
Nested table cells contain JSON text. `<collection>_encoding.json_columns` names
|
|
22
|
+
every column using this codec; all present cells in such a column use JSON,
|
|
23
|
+
including scalar cells, so strings that resemble JSON remain distinguishable.
|
|
24
|
+
`absent` contains `[row_index, column_name]` pairs for missing fields. Null padding
|
|
25
|
+
does not imply an explicit null in the original object. Column order follows
|
|
26
|
+
first occurrence; row order, ranking, identities, and nested facts are preserved.
|
|
27
|
+
A producer-owned `<collection>_encoding` field prevents this transformation.
|
|
28
|
+
|
|
29
|
+
Package authors can use `encodePmTableRows` and `decodePmTableRows` from
|
|
30
|
+
`@unbrained/pm-cli/sdk`. The helpers accept JSON object rows and return primitive
|
|
31
|
+
cells plus explicit restoration metadata. They preserve empty containers, nulls,
|
|
32
|
+
false, zero, sparse keys, and arbitrary JSON strings. The CLI's existing sparse
|
|
33
|
+
projection runs before encoding; the codec itself never drops those values.
|
|
34
|
+
Malformed JSON cells throw instead of silently changing their meaning.
|
|
35
|
+
Explicit codec calls construct a dense grid proportional to row count times
|
|
36
|
+
distinct-column count; package authors must budget that allocation for sparse
|
|
37
|
+
inputs. This public codec does not impose a row cap or silently change encoding.
|
|
38
|
+
|
|
39
|
+
The TOON presentation of an item prints `collection_counts.notes` and
|
|
40
|
+
`collection_counts.tests` once, suppressing `notes_count` or `tests_count` only
|
|
41
|
+
when the alias equals its canonical count. Zero counts and differing values stay
|
|
42
|
+
visible. JSON, including explicit lean JSON, continues to carry the legacy keys.
|
|
43
|
+
|
|
44
|
+
## Measurement and readability
|
|
45
|
+
|
|
46
|
+
The reproducible fixtures in `tests/unit/sdk/output/table-rows.spec.ts` cover search,
|
|
47
|
+
next-work selection, ranked context, and entity evidence at 1, 8, and 32 rows.
|
|
48
|
+
Each includes nested facts. The historical renderer is measured at commit
|
|
49
|
+
`5f8ae4d00d77357cbce7e5546569231d02fa7b00`. Token counts use pinned
|
|
50
|
+
`gpt-tokenizer@4.0.0`, encoding `o200k_base`, rather than the runtime byte estimate.
|
|
51
|
+
Measurements are committed in `tests/fixtures/agent-encoding-baseline.json`.
|
|
52
|
+
|
|
53
|
+
| Surface / rows | Previous TOON | JSON | Nested TOON | Hoisted cells | Ordinal | Selected |
|
|
54
|
+
| -------------- | ------------: | ---: | ----------: | ------------: | ------: | -------: |
|
|
55
|
+
| search / 1 | 83 | 110 | 70 | 86 | 88 | 73 |
|
|
56
|
+
| search / 8 | 503 | 607 | 406 | 303 | 417 | 303 |
|
|
57
|
+
| search / 32 | 1943 | 2311 | 1558 | 1047 | 1545 | 1047 |
|
|
58
|
+
| next / 1 | 86 | 122 | 76 | 94 | 93 | 79 |
|
|
59
|
+
| next / 8 | 527 | 703 | 454 | 367 | 457 | 367 |
|
|
60
|
+
| next / 32 | 2039 | 2695 | 1750 | 1303 | 1705 | 1303 |
|
|
61
|
+
| context / 1 | 89 | 118 | 76 | 89 | 95 | 79 |
|
|
62
|
+
| context / 8 | 544 | 664 | 447 | 320 | 459 | 321 |
|
|
63
|
+
| context / 32 | 2104 | 2536 | 1719 | 1112 | 1707 | 1113 |
|
|
64
|
+
| get / 1 | 86 | 124 | 76 | 115 | 106 | 80 |
|
|
65
|
+
| get / 8 | 408 | 551 | 279 | 311 | 400 | 264 |
|
|
66
|
+
| get / 32 | 1512 | 2015 | 975 | 983 | 1408 | 840 |
|
|
67
|
+
|
|
68
|
+
These are fixture measurements, not universal compression guarantees. Selected
|
|
69
|
+
output combines the existing scalar presentation with a per-collection choice,
|
|
70
|
+
so it can differ from a whole-document candidate. The runtime compares bytes;
|
|
71
|
+
the mandatory full test suite independently enforces token and byte ratchets.
|
|
72
|
+
Information equivalence is checked by standard TOON decoding and explicit cell
|
|
73
|
+
restoration, including a negative comparison against an answer missing facts.
|
|
74
|
+
|
|
75
|
+
Readability requires discoverable column names, unchanged row order, visible
|
|
76
|
+
identities, explicit nested-cell metadata, and complete recovery/omission facts.
|
|
77
|
+
The review scores one point for each of those five properties, then subtracts
|
|
78
|
+
one for an extra JSON-cell decoding step or two for positional row interpretation.
|
|
79
|
+
The minimum adopted score is four; it is a design criterion alongside the
|
|
80
|
+
independent executable equivalence gate.
|
|
81
|
+
|
|
82
|
+
| Candidate | Readability score / 5 | Interpretation |
|
|
83
|
+
| --------------- | --------------------: | ----------------------------------------- |
|
|
84
|
+
| JSON | 5 | Named fields and native nested values |
|
|
85
|
+
| Nested TOON | 5 | Named fields and standard nested decoding |
|
|
86
|
+
| Hoisted cells | 4 | Named columns and declared JSON cells |
|
|
87
|
+
| Ordinal | 3 | Column lookup plus positional nested rows |
|
|
88
|
+
| Selected hybrid | 4–5 | Expanded small rows or declared tables |
|
|
89
|
+
|
|
90
|
+
Ordinal arrays require an additional positional interpretation and save nothing
|
|
91
|
+
on these nested fixtures, so they are not adopted. The complete brief-list
|
|
92
|
+
projection and existing flat-table defaults retain their earlier policy.
|
|
93
|
+
The [TOON benchmark methodology](https://toonformat.dev/guide/benchmarks) motivates
|
|
94
|
+
measuring uniform and nested shapes separately rather than assuming one encoding
|
|
95
|
+
wins everywhere.
|
|
96
|
+
|
|
97
|
+
Run the focused equivalence and token gate with:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
node scripts/run-tests.mjs test -- tests/unit/sdk/output/table-rows.spec.ts tests/unit/cli/compact-agent-output.spec.ts
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Context budget boundary
|
|
104
|
+
|
|
105
|
+
For complete JSON/TOON responses, `pm context --token-budget 800` now bounds the
|
|
106
|
+
whole rendered envelope: focus, agenda, extension health, provenance, and final
|
|
107
|
+
receipts. `read_output.estimated_tokens` uses `ceil(UTF-8 bytes / 4)`, including
|
|
108
|
+
the final newline, and reports whether the response fits. The compatibility
|
|
109
|
+
ceiling is disclosed as `budget_source: legacy` and `budget_tokens`.
|
|
110
|
+
When an enforced context intent already discloses the same ceiling, its receipt
|
|
111
|
+
is reused. Session accounting still includes the complete envelope. A mismatched
|
|
112
|
+
or unenforced intent receipt never suppresses compatibility-budget evidence.
|
|
113
|
+
|
|
114
|
+
The SDK applies the same rule to `tokenBudget` and `token_budget`. Canonical
|
|
115
|
+
`outputBudget` / `--output-budget` takes precedence. A budget too small for the
|
|
116
|
+
answer returns an explicit omission receipt and recovery; it does not pretend
|
|
117
|
+
that omitted work is an empty population. Use `--output-budget unbounded` to
|
|
118
|
+
request the complete result. Markdown, NDJSON, and other command-specific
|
|
119
|
+
streaming budgets remain separate contracts.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Faithful package acceptance
|
|
2
|
+
|
|
3
|
+
Tracked by [pm-gh1391](../.agents/pm/issues/pm-gh1391.toon),
|
|
4
|
+
[pm-aiqmgj](../.agents/pm/issues/pm-aiqmgj.toon), and
|
|
5
|
+
[pm-dqej6b](../.agents/pm/issues/pm-dqej6b.toon), with scratch ancestry protection
|
|
6
|
+
tracked by [pm-runner-ancestor-tracker](../.agents/pm/issues/pm-runner-ancestor-tracker.toon).
|
|
7
|
+
|
|
8
|
+
Package tests that create their own disposable projects need an unset `PM_PATH`.
|
|
9
|
+
Otherwise a nested `pm init` follows the inherited tracker override and writes
|
|
10
|
+
outside the intended fixture. Use the shared SDK linked-test runner with a
|
|
11
|
+
disposable source snapshot:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pm test <item-id> --add-json '{"command":"npm run release:check","pm_context_mode":"none","workspace_context_mode":"snapshot","timeout_seconds":900}'
|
|
15
|
+
pm test <item-id> --run --progress
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The same fields are supported by the SDK's `runTest` and MCP. See
|
|
19
|
+
[Testing](TESTING.md) for trust acknowledgements, assertions and run receipts.
|
|
20
|
+
|
|
21
|
+
Snapshots copy the current source files and keep root and nested `node_modules`
|
|
22
|
+
at their original relative paths. A Git workspace additionally receives an
|
|
23
|
+
independent clone of commit and tag objects, so release-tag checks and dependency
|
|
24
|
+
resolution work together. The clone uses no shared objects or source hooks,
|
|
25
|
+
does not inherit source-local Git configuration, and has no origin remote.
|
|
26
|
+
The internal remote name is explicit even with a custom `clone.defaultRemoteName`.
|
|
27
|
+
Its Git objects remain readable after the source checkout is removed.
|
|
28
|
+
|
|
29
|
+
The working tree excludes tracker and generated build/report directories.
|
|
30
|
+
Git objects contain repository history, including any historically tracked
|
|
31
|
+
files; a snapshot is an execution-isolation boundary, not a redaction mechanism.
|
|
32
|
+
Source aliases remain subject to containment checks. Installed dependency
|
|
33
|
+
directories are shared, so dependency-mutating tests need a separate installation.
|
|
34
|
+
Tests that depend on absolute checkout paths, source-local Git configuration,
|
|
35
|
+
submodule configuration, or exact dirty-status output must declare those
|
|
36
|
+
requirements separately. Cloning failures fail the linked run rather than
|
|
37
|
+
silently certifying a partial Git identity.
|
|
38
|
+
|
|
39
|
+
`PM_GLOBAL_PATH` remains isolated. `none` with a live source workspace and direct
|
|
40
|
+
PM commands remains refused. Existing command provenance and clone-local trust
|
|
41
|
+
checks still apply. The runner records the effective workspace and tracker
|
|
42
|
+
context on each execution so a green linked receipt identifies its boundary.
|
|
43
|
+
Repository acceptance also refuses scratch roots beneath any initialized
|
|
44
|
+
ancestor tracker before allocating fixtures, including external roots and
|
|
45
|
+
root-layout trackers. Choose a temporary hierarchy without workspace ancestry.
|
|
46
|
+
|
|
47
|
+
The optional SQLite accelerator filters Node's exact experimental announcement
|
|
48
|
+
only during synchronous native loading. Every other warning retains its original
|
|
49
|
+
arguments, and normal warning delivery is restored immediately, including after
|
|
50
|
+
a failed optional load. JSON refusals and clean mutation stderr therefore remain
|
|
51
|
+
usable on Node 22 and Node 24 without disabling application diagnostics.
|
|
52
|
+
|
|
53
|
+
The repository's scratch lifecycle keeps its original 15-second latency and
|
|
54
|
+
3,000-token output limits. Vitest schedules it in a separate project after the
|
|
55
|
+
parallel contract suite. Functional assertions and the all-source coverage
|
|
56
|
+
denominator stay intact; a real latency regression still fails admission.
|
package/docs/README.md
CHANGED
|
@@ -35,6 +35,7 @@ pm guide release --json
|
|
|
35
35
|
- [Onboarding](ONBOARDING.md) - first-two-hours maintainer and contributor setup.
|
|
36
36
|
- [Agent Guide](AGENT_GUIDE.md) - canonical agent loop, tracker linking, and token-minimal command choices.
|
|
37
37
|
- [Agent Read and Test Receipts](AGENT_READ_AND_TEST_RECEIPTS.md) - JSON help provenance, linked-test persistence, and history diff continuation.
|
|
38
|
+
- [Fact-preserving Agent Output](AGENT_OUTPUT_ENCODINGS.md) - lossless SDK table cells, measured token ratchets, count aliases, and whole-response context budgets.
|
|
38
39
|
- [Agent Evidence Consistency](AGENT_EVIDENCE_CONSISTENCY.md) - literal annotations, concurrent history validation, and declared recovery help.
|
|
39
40
|
- [Actionable Item-read Evidence](GET_READ_EVIDENCE.md) - declared blocker status, historical separation, and truthful schedule/artifact omission receipts.
|
|
40
41
|
- [Command Reference](COMMANDS.md) - command families with examples and when to use each family.
|
|
@@ -43,6 +44,7 @@ pm guide release --json
|
|
|
43
44
|
- [Configuration](CONFIGURATION.md) - settings, storage formats, output, search, validation, and environment variables.
|
|
44
45
|
- [Semantic Batching and Retrieval Quality](SEARCH_QUALITY.md) - independent request bounds, execution receipts, and per-query quality floors.
|
|
45
46
|
- [Testing](TESTING.md) - sandbox-safe local tests and linked-test orchestration.
|
|
47
|
+
- [Faithful Package Acceptance](PACKAGE_GATE_ACCEPTANCE.md) - self-isolating package gates, independent Git snapshots, native diagnostics and isolated timing admission.
|
|
46
48
|
- [Completion Portability and Bounded Replication Checks](VALIDATION_PORTABILITY.md) - literal Bash choices across versions and locales, and semantic Git diff collection.
|
|
47
49
|
- [Build and Release Acceptance](BUILD_AND_RELEASE_ACCEPTANCE.md) - complete-build leases and cross-platform registry installation controls.
|
|
48
50
|
- [Security Governance](SECURITY_GOVERNANCE.md) - vulnerability reporting, review discipline, property fuzzing, and OpenSSF limitations.
|
package/docs/TESTING.md
CHANGED
|
@@ -57,8 +57,12 @@ fixtures must never create production incidents from a developer host.
|
|
|
57
57
|
|
|
58
58
|
Temporary directories must live outside the checkout and outside any ancestor
|
|
59
59
|
workspace with initialized tracker data. The runner rejects a checkout-local
|
|
60
|
-
temporary root
|
|
61
|
-
|
|
60
|
+
temporary root and every initialized standard or root-layout ancestor tracker,
|
|
61
|
+
including physical symlink aliases, before allocating fixtures or starting build
|
|
62
|
+
or test processes ([pm-bukwmy](../.agents/pm/issues/pm-bukwmy.toon),
|
|
63
|
+
[pm-runner-ancestor-tracker](../.agents/pm/issues/pm-runner-ancestor-tracker.toon)).
|
|
64
|
+
Unrelated valid settings files remain admissible; unreadable or invalid ancestor
|
|
65
|
+
settings refuse ancestry certification. If the default
|
|
62
66
|
temporary filesystem is full, set `TMPDIR` (or `TEMP`/`TMP` on Windows) to an
|
|
63
67
|
existing isolated scratch directory; an ignored directory inside the repository
|
|
64
68
|
is not isolated. Filesystem fixtures must honor `node:os`'s `tmpdir()` and remove
|
|
@@ -549,7 +553,11 @@ pm test <item-id> --run --workspace-context snapshot --override-linked-workspace
|
|
|
549
553
|
copy, and binds its `.agents/pm` path to the selected temporary tracker.
|
|
550
554
|
`.git`, `.agents`, coverage output, and common cache directories are excluded
|
|
551
555
|
at every directory depth, with reserved names matched case-insensitively for
|
|
552
|
-
portable admission.
|
|
556
|
+
portable admission. Git sources receive an independent commit/tag object store
|
|
557
|
+
with fresh configuration, no source hooks, and no origin remote. Repository
|
|
558
|
+
history remains available; this is execution isolation, not history redaction.
|
|
559
|
+
See [Faithful package acceptance](PACKAGE_GATE_ACCEPTANCE.md) for limits.
|
|
560
|
+
Each existing root or nested `node_modules`
|
|
553
561
|
directory is linked at its original relative path, including installations
|
|
554
562
|
already represented by directory symlinks. This preserves independent
|
|
555
563
|
monorepo dependency versions without copying dependency trees. Dependency
|
package/marketplace.json
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
"url": "https://github.com/unbraind/pm-cli"
|
|
6
6
|
},
|
|
7
7
|
"description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
|
|
8
|
-
"version": "2026.10.
|
|
8
|
+
"version": "2026.10.9",
|
|
9
9
|
"plugins": [
|
|
10
10
|
{
|
|
11
11
|
"name": "pm-claude",
|
|
12
12
|
"source": "./plugins/pm-claude",
|
|
13
13
|
"description": "Native pm CLI integration for Claude Code — 32 MCP tools, 14 workflow skills with slash invocations, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
|
|
14
|
-
"version": "2026.10.
|
|
14
|
+
"version": "2026.10.9",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "unbrained",
|
|
17
17
|
"url": "https://github.com/unbraind/pm-cli"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-digital-twin",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.9",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Beyond-PM exemplar: a temporal production-facility digital twin built entirely on public pm SDK and extension primitives.",
|