@unbrained/pm-cli 2026.10.19 → 2026.10.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +33 -0
- package/dist/cli/error-guidance.d.ts +7 -0
- package/dist/cli/error-guidance.js +2 -2
- package/dist/cli/register-structured-mutation.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +1 -1
- package/dist/cli-bundle/chunks/{chunk-QBNEZII5.js → chunk-2GGGOD7P.js} +13 -13
- package/dist/cli-bundle/chunks/{chunk-4CXQSRSP.js → chunk-7NHA5K77.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NX7Q4LGN.js → chunk-7ZOIZ2AZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-6DS5CAN2.js → chunk-GHJOMRSF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-O2ZRRLAP.js → chunk-KU4Q3MSI.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-DMFM5R4G.js → chunk-LS55VKRK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-QG4LMU7A.js → chunk-PNPE2OVJ.js} +43 -43
- package/dist/cli-bundle/chunks/chunk-PTL3TBT6.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-LBEMB3BW.js → chunk-QETMESEB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4MJ6WBMA.js → chunk-QMZ73FCW.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-QQYCB2LO.js +2 -0
- package/dist/cli-bundle/chunks/chunk-TZU6U5ZE.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-H3XYP24A.js → chunk-VLJLWZBO.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-XAWE4EAK.js +2 -0
- package/dist/cli-bundle/chunks/chunk-YECCKB4E.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-5GZSX5HU.js → chunk-YT2Z3JPC.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-4XFVAXA4.js → chunk-YTHI5DTH.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-D3EDNAN7.js → chunk-YW6SIKYP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XH7C3A5N.js → chunk-ZA3XXHEE.js} +6 -6
- package/dist/cli-bundle/chunks/context-budget-recovery-L2WP5S26.js +2 -0
- package/dist/cli-bundle/{focused-chunks/indexed-receipt-blobs-QW2VWWJE.js → chunks/indexed-receipt-blobs-U7VGKIYC.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-WQUVDJIH.js → register-list-query-NNDV6F6I.js} +3 -3
- package/dist/cli-bundle/chunks/{register-mutation-IWIBQIO3.js → register-mutation-3GCBSNQS.js} +4 -4
- package/dist/cli-bundle/chunks/register-operations-YKDGNKUL.js +2 -0
- package/dist/cli-bundle/chunks/register-setup-AOUZQQWB.js +2 -0
- package/dist/cli-bundle/chunks/{settlement-hook-UNFMCKKQ.js → settlement-hook-CLRGA6O7.js} +2 -2
- package/dist/cli-bundle/chunks/stage-6QXYRMSU.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-WZTEFFQI.js → chunk-37SU7BZI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5YTOYBTZ.js → chunk-6IU7BESB.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-AS3MOBO3.js +25 -0
- package/dist/cli-bundle/focused-chunks/{chunk-PXDR77TO.js → chunk-AW35RDKA.js} +22 -22
- package/dist/cli-bundle/focused-chunks/{chunk-RLRMNFLF.js → chunk-E4II2D2B.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FEN7WOOP.js → chunk-F7FD25TG.js} +12 -12
- package/dist/cli-bundle/focused-chunks/{chunk-JDBO7SMR.js → chunk-GYHZ7W6O.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-EOQ6W25I.js → chunk-H5Q2HUU6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-3TEIACFU.js → chunk-HUZAXSIJ.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-JBJJW2WL.js → chunk-J6EYUGAR.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-JEXZEIAX.js +91 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ENZMATOY.js → chunk-KDGUIIRU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-H6BVQ63U.js → chunk-KKRFSI2N.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-GWTV45SB.js → chunk-LJPUJ2KK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-MQ42BFGX.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-HYMYAGSY.js → chunk-NI6NS44Q.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-L4PL3GZR.js → chunk-VAYS754X.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-SKYLOPU2.js → chunk-VLSER3XW.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-JCLC6HKT.js → chunk-VS6VTWTZ.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-OV2WVLUR.js → chunk-ZGEK57KD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/context-budget-recovery-5MKOCGY5.js +2 -0
- package/dist/cli-bundle/{chunks/indexed-receipt-blobs-BVSHK4WQ.js → focused-chunks/indexed-receipt-blobs-H2G6CCGO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{settlement-hook-X4FNHTOD.js → settlement-hook-5SNBBT7C.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{stage-MZSVQYO4.js → stage-EMTISXR7.js} +2 -2
- package/dist/cli-bundle/main.js +21 -21
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +2 -2
- package/dist/cli-bundle/sdk-core.js +21 -21
- 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 +55 -55
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +8 -8
- package/dist/core/fs/fs-utils.d.ts +2 -2
- package/dist/core/fs/fs-utils.js +1 -1
- package/dist/core/history/event-index.js +2 -2
- package/dist/core/output/output.d.ts +7 -2
- package/dist/core/output/output.js +5 -5
- package/dist/core/shared/errors.d.ts +48 -0
- package/dist/core/shared/errors.js +1 -1
- package/dist/core/store/settings.js +2 -2
- package/dist/mcp/server.js +1 -1
- package/dist/sdk/core.d.ts +1 -1
- package/dist/sdk/core.js +1 -1
- package/dist/sdk/dependencies/context-budget-recovery.d.ts +21 -0
- package/dist/sdk/dependencies/context-budget-recovery.js +2 -0
- package/dist/sdk/dependencies.js +1 -1
- package/dist/sdk/errors.d.ts +4 -1
- package/dist/sdk/errors.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/item-transaction.d.ts +13 -0
- package/dist/sdk/item-transaction.js +1 -1
- package/dist/sdk/lifecycle/structured-mutation-plan.d.ts +14 -1
- package/dist/sdk/lifecycle/structured-mutation-plan.js +1 -1
- package/dist/sdk/output/list-envelope.d.ts +7 -0
- package/dist/sdk/output/list-envelope.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/relationship-context.d.ts +2 -0
- package/dist/sdk/relationship-context.js +1 -1
- package/dist/sdk/structured-mutations.d.ts +2 -0
- package/dist/sdk/structured-mutations.js +1 -1
- package/docs/COMMANDS.md +14 -0
- package/docs/PR_REVIEW_LOOP.md +32 -12
- package/docs/SCRIPTING.md +10 -0
- package/docs/SDK.md +77 -0
- package/docs/TESTING.md +25 -1
- package/marketplace.json +1 -1
- 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 +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +1 -1
- package/plugins/pm-codex/plugin.json +1 -1
- package/runtime-dependencies.json +1 -1
- package/dist/cli-bundle/chunks/chunk-4ICKT4GH.js +0 -3
- package/dist/cli-bundle/chunks/chunk-OEJ3G7XT.js +0 -20
- package/dist/cli-bundle/chunks/chunk-QKAAZWGC.js +0 -3
- package/dist/cli-bundle/chunks/chunk-TK3G3GAP.js +0 -2
- package/dist/cli-bundle/chunks/register-operations-SUWOZNDU.js +0 -2
- package/dist/cli-bundle/chunks/register-setup-QGM5YJW7.js +0 -2
- package/dist/cli-bundle/chunks/stage-7DELI4Z5.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2IEWB6MB.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-BJMPRB7A.js +0 -91
- package/dist/cli-bundle/focused-chunks/chunk-KLJN44VY.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-Y54ONBEX.js +0 -25
package/dist/mcp/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
(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]="4f5b83c9-8f48-5a2c-9058-cd993d25dc98")}catch{}})();import{realpathSync}from"node:fs";import{readFile}from"node:fs/promises";import path from"node:path";import readline from"node:readline";import{fileURLToPath}from"node:url";import{resolvePmCliVersion,EXIT_CODE,PmCliError,decodeHtmlEntitiesInOptions,levenshteinDistanceWithinLimit,asRecordClone,createSerialQueue,evaluateMutationGuard,getSettingsPath,isMutationAction,pathExists,readSettings,runWithHarnessDetectionSignals,runWithWorkspaceHarnessSignalDescriptors,boundAgentEpisodeIdentity}from"../sdk/runtime-primitives.js";import{pmToolActionNestedOptionKeys}from"../sdk/cli-contracts/tool-schema.js";import{readRequiredString,runAction,runWithActiveExtensions}from"../sdk/runtime.js";import{NARROW_TOOL_ACTIONS,TOOLS}from"./tool-definitions.js";import{normalizeWorkspaceToolArguments,resolveMcpToolAccess,resolveMcpToolSurface}from"./runtime-capabilities.js";import{PM_MCP_PROMPT_CONTRACTS,PM_MCP_RESOURCE_CONTRACTS}from"../sdk/agent-capability-contracts.js";import{PM_MCP_ENTRY_TOOL_NAMES,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION,PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY,discoverPmTools,parsePmToolDiscoveryOptions}from"../sdk/mcp/discovery.js";import{commitItemMutations,previewItemMutations}from"../sdk/item-transaction.js";import{isRuntimeRecord,markMcpMutationTransportInput}from"../sdk/runtime-input.js";import{attachOutputTokenAccounting}from"../sdk/output-token-accounting.js";import{createReproducibleProcessRunner,runWithReproducibleProcessEnvironment}from"../sdk/reproducibility/process.js";import{parseAtomicMutationControls}from"../sdk/structured-mutations.js";import{planItemMutationDocument}from"../sdk/lifecycle/structured-mutation-plan.js";import{resolveAuthor,resolvePmRoot,resolveWorkspaceRoot}from"../sdk/runtime-primitives.js";import{PM_MCP_ERROR_CODES,PM_MCP_META_KEYS,PM_MCP_PROTOCOL_VERSION,PmMcpProtocolError,attachMcpServerInfo,buildMcpCompleteResult,buildMcpDiscoverResult,hasMcpClientExtension,isMcpRecord,resolveMcpRequestContext}from"../sdk/mcp/protocol.js";import{PmMcpInputRequiredError,buildMcpInputRequiredResult,parseMcpInputResponses,validateMcpJsonSchema,withMcpCachePolicy}from"../sdk/mcp/interactions.js";import{PM_MCP_TASKS_EXTENSION,createMcpTaskStore}from"../sdk/mcp/tasks.js";import{PmMcpSubscriptionRegistry}from"../sdk/mcp/subscriptions.js";import{extractMcpTraceContext,runWithMcpTraceContext}from"../sdk/mcp/authorization.js";import{LegacyMcpAdapter}from"./legacy-adapter.js";import{PM_MCP_APP_CONTRACTS,PM_MCP_APP_MIME_TYPE,PM_MCP_APPS_EXTENSION,PM_MCP_APPS_SERVER_CAPABILITY,decoratePmMcpToolsWithApps,findPmMcpAppByUri,hasPmMcpAppsCapability,renderPmMcpAppHtml}from"../sdk/mcp/apps.js";import{PM_MCP_SKILLS_EXTENSION,PM_MCP_SKILLS_SERVER_CAPABILITY,PmMcpSkillRegistry,assertPmMcpSkillsCapability}from"../sdk/mcp/skills.js";function runMcpAction(args){return runAction(markMcpMutationTransportInput(args))}const PM_PACKAGE_ROOT_ENV="PM_CLI_PACKAGE_ROOT";function resolvePmPackageRoot(){return fileURLToPath(new URL("../..",import.meta.url))}(typeof process.env[PM_PACKAGE_ROOT_ENV]!="string"||process.env[PM_PACKAGE_ROOT_ENV]?.trim().length===0)&&(process.env[PM_PACKAGE_ROOT_ENV]=resolvePmPackageRoot());const PM_MCP_SERVER_VERSION=resolvePmCliVersion(import.meta.url,["../.."])??"0.0.0",PM_MCP_SERVER_INFO={name:"pm-mcp",version:PM_MCP_SERVER_VERSION,description:"Stateless project-context management through pm SDK contracts.",websiteUrl:"https://github.com/unbraind/pm-cli"},PM_MCP_SERVER_CAPABILITIES={prompts:{listChanged:!0},resources:{listChanged:!0,subscribe:!0},tools:{listChanged:!0},extensions:{[PM_MCP_TASKS_EXTENSION]:{},[PM_MCP_APPS_EXTENSION]:PM_MCP_APPS_SERVER_CAPABILITY,[PM_MCP_SKILLS_EXTENSION]:PM_MCP_SKILLS_SERVER_CAPABILITY,[PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION]:PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY}},PM_MCP_SUBSCRIPTIONS=new Map;function createMcpSubscriptionRegistry(){return new PmMcpSubscriptionRegistry({capabilities:PM_MCP_SERVER_CAPABILITIES,serverInfo:PM_MCP_SERVER_INFO})}function pruneClosedMcpSubscriptionRegistries(){for(const[key,subscription]of PM_MCP_SUBSCRIPTIONS)subscription.registry.size===0&&PM_MCP_SUBSCRIPTIONS.delete(key)}const PM_MCP_CACHE_POLICIES={prompts:{ttlMs:6e4,cacheScope:"public"},resource:{ttlMs:0,cacheScope:"private"},resources:{ttlMs:6e4,cacheScope:"public"},tools:{ttlMs:3e4,cacheScope:"private"}},PM_MCP_DIRECT_TASK_TOOLS=new Set(["pm_graph","pm_health","pm_validate"]),PM_MCP_RUN_TASK_ACTIONS=new Set(["graph","health","import","reindex","test-all","validate"]),PM_MCP_SKILL_METHODS=new Set(["skills/list","skills/get","resources/directory/read"]),PM_MCP_INSTRUCTIONS="You have access to native pm CLI tools for git-based project management. When progressive discovery is negotiated, use pm_discover to expand the small entry catalog by intent and request schemas only when needed. Use pm_next to pick the next actionable item, or pm_context or pm_search before creating new work. Prefer narrow tools (pm_next, pm_context, pm_list, pm_get, pm_search, pm_events, pm_create, pm_mutate, pm_copy, pm_focus, pm_update, pm_append, pm_claim, pm_release, pm_close, pm_comments, pm_files, pm_docs, pm_notes, pm_learnings, pm_deps, pm_graph, pm_test, pm_validate, pm_health, pm_contracts, pm_schema, pm_profile, pm_config, pm_plan) over pm_run when they cover the operation. Use pm_plan for agent harness Plan workflows: it provides Codex/Claude/Cursor-style planning with durable steps, dependencies, decisions, discoveries, validation, and materialization. Use pm_schema and pm_config for workspace configuration: pm_schema manages custom item types/statuses and pm_config reads or writes settings keys. Use pm_run with an explicit action for active package-owned operations, plus activity, aggregate, history, stats, test-all, and gc. Use history-redact for audited history-stream redaction workflows, history-repair to re-anchor a drifted history chain, and history-compact to checkpoint/prune long history streams while preserving replay integrity. Agent harness and model provenance are detected automatically; pass author only for an intentional identity override. Do not pass path during real repository tracking \u2014 only pass path for sandbox or test runs.";function declaredToolKeys(tools=TOOLS){return new Map(tools.map(tool=>{const properties=tool.inputSchema.properties??{};return[tool.name,Object.keys(properties)]}))}function nearestDeclaredKey(unexpected,declared){const limit=Math.max(1,Math.min(3,Math.floor(unexpected.length/4)+1));let best;for(const candidate of declared){const distance=levenshteinDistanceWithinLimit(unexpected,candidate,limit);distance!==null&&(best===void 0||distance<best.distance)&&(best={key:candidate,distance})}return best?.key}const UNEXPECTED_KEY_WARNING_EXEMPT_TOOLS=new Set(["pm_run"]),MCP_RETRY_ARGUMENT_KEYS=new Set(["inputResponses","requestState"]);function resolveMcpDiscoveryCursorIntegrityKey(){const configuredKey=process.env.PM_MCP_DISCOVERY_CURSOR_KEY;if(configuredKey===void 0)return;const key=Buffer.from(configuredKey,"utf8");if(key.byteLength<32)throw new PmCliError("PM_MCP_DISCOVERY_CURSOR_KEY must contain at least 32 UTF-8 bytes.",64);return key}function detectUnexpectedTopLevelKeys(toolName,args,toolDeclaredKeys=declaredToolKeys()){if(typeof args!="object"||args===null||Array.isArray(args))return[];if(UNEXPECTED_KEY_WARNING_EXEMPT_TOOLS.has(toolName))return[];const declared=toolDeclaredKeys.get(toolName);if(declared===void 0)return[];const declaredSet=new Set([...declared,...MCP_RETRY_ARGUMENT_KEYS]),warnings=[];for(const key of Object.keys(args)){if(declaredSet.has(key))continue;const suggestion=nearestDeclaredKey(key,declared);warnings.push(suggestion!==void 0?`Unexpected top-level argument "${key}" for ${toolName} (did you mean "${suggestion}"?). It is not declared and may be ignored; declared arguments are: ${declared.join(", ")}.`:`Unexpected top-level argument "${key}" for ${toolName}. It is not declared and may be ignored; declared arguments are: ${declared.join(", ")}.`)}return warnings}const HANDLERS={pm_run:args=>runMcpAction(args),pm_discover:async args=>{const surface=await resolveMcpToolSurface(TOOLS,args),cursorIntegrityKey=resolveMcpDiscoveryCursorIntegrityKey(),discoveryOptions=parsePmToolDiscoveryOptions(args);return discoverPmTools(surface.tools.map(tool=>({name:tool.name,description:tool.description,inputSchema:tool.inputSchema,authorized:!0,signals:{freshness:1,usage:PM_MCP_ENTRY_TOOL_NAMES.includes(tool.name)?1:0}})),{...discoveryOptions,profile:surface.profile,...cursorIntegrityKey===void 0?{}:{cursorIntegrityKey}})},pm_mutate:async args=>{if(!Array.isArray(args.mutations)||args.mutations.length===0)throw new PmCliError("pm_mutate requires a non-empty mutations array.",EXIT_CODE.USAGE);const explicitTransactionId=args.transactionId===void 0?void 0:readRequiredString(args,"transactionId"),upsertKey=args.upsertKey===void 0?void 0:readRequiredString(args,"upsertKey"),controls=parseAtomicMutationControls(args),cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),pmRoot=resolvePmRoot(cwd,typeof args.path=="string"?args.path:void 0),extensionScope={cwd:typeof args.cwd=="string"?args.cwd:void 0,path:pmRoot,noExtensions:args.noExtensions===!0},plan=await runWithActiveExtensions(extensionScope,()=>planItemMutationDocument({pmRoot,input:JSON.stringify({schema_version:1,mutations:args.mutations}),...explicitTransactionId===void 0?{}:{transactionId:explicitTransactionId},...upsertKey===void 0?{}:{upsertKey}})),{mutations,references,rows}=plan,transactionId=plan.transaction_id,receipt={transaction_id:transactionId,transaction_id_source:plan.transaction_id_source,...plan.upsert_key===void 0?{}:{upsert_key:plan.upsert_key}};if(args.dryRun===!0){const validation=await runWithActiveExtensions(extensionScope,()=>previewItemMutations({pmRoot,transactionId,author:resolveAuthor(typeof args.author=="string"?args.author:void 0,"unknown"),mutations}));return{...receipt,dry_run:!0,validation,mutation_count:mutations.length,mutations,references,rows}}const result=await runWithActiveExtensions(extensionScope,()=>commitItemMutations({pmRoot,transactionId,author:resolveAuthor(typeof args.author=="string"?args.author:void 0,"unknown"),mutations,...controls}));return{...Object.fromEntries(Object.entries(result).filter(([key])=>key!=="transactionId")),...receipt,mutation_count:mutations.length,references,rows}},...Object.fromEntries(Object.entries(NARROW_TOOL_ACTIONS).map(([tool,action])=>[tool,args=>runMcpAction({...args,action})]))};function resolveInvokedAction(toolName,args){return toolName==="pm_run"?typeof args.action=="string"?args.action:void 0:NARROW_TOOL_ACTIONS[toolName]}async function collectMutationGuardWarnings(toolName,action,args){if(toolName!=="pm_mutate"&&!isMutationAction(action??""))return[];const cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),pmRoot=resolvePmRoot(cwd,typeof args.path=="string"?args.path:void 0);if(!await pathExists(getSettingsPath(pmRoot)))return[];const settings=await readSettings(pmRoot),nestedOptions=typeof args.options=="object"&&args.options!==null&&!Array.isArray(args.options)?args.options:{};return evaluateMutationGuard({author:resolveAuthor(typeof args.author=="string"?args.author:typeof nestedOptions.author=="string"?nestedOptions.author:void 0,settings.author_default),payload:Object.fromEntries(Object.entries(args).filter(([key])=>key!=="cwd"&&key!=="path")),settings:settings.mutation_guard,force:args.force===!0||nestedOptions.force===!0}).warnings}function detectUnexpectedOptionKeys(toolName,action,args){const options=args.options;if(action===void 0||typeof options!="object"||options===null||Array.isArray(options))return[];const declared=pmToolActionNestedOptionKeys(action);if(declared===void 0)return[];const declaredSet=new Set(declared),warnings=[];for(const key of Object.keys(options)){if(declaredSet.has(key))continue;const suggestion=nearestDeclaredKey(key,declared);warnings.push(suggestion!==void 0?`Unknown option "${key}" for ${toolName} action "${action}" (did you mean "${suggestion}"?). The ${action} contract does not read it, so it has no effect; declared keys are: ${declared.join(", ")}.`:`Unknown option "${key}" for ${toolName} action "${action}". The ${action} contract does not read it, so it has no effect; declared keys are: ${declared.join(", ")}.`)}return warnings}function resultContent(result,warnings,tokenAccounting=!1,canonicalStructuredResult=!1){const effectiveResult=tokenAccounting?attachOutputTokenAccounting(result,value=>JSON.stringify(value,null,2)):result,structuredContent=warnings!==void 0&&warnings.length>0?{result:effectiveResult,warnings}:{result:effectiveResult};return{content:[{type:"text",text:canonicalStructuredResult?"Canonical result: structuredContent.result":JSON.stringify(effectiveResult,null,2)}],structuredContent}}function errorContent(error,canonicalStructuredResult=!1){const code=error instanceof PmCliError?error.exitCode:1,message=error instanceof Error?error.message:String(error),details=error instanceof PmCliError?error.context:void 0;return{isError:!0,content:[{type:"text",text:canonicalStructuredResult?"Canonical error: structuredContent":JSON.stringify({error:message,code,details},null,2)}],structuredContent:{result:null,error:message,code,details}}}function boundMcpClientProvenance(value){const provenance=isRuntimeRecord(value)?value:{},bounded={};let acceptedCount=0;for(const key in provenance){if(acceptedCount>=32)break;if(!Object.prototype.hasOwnProperty.call(provenance,key))continue;const entry=provenance[key];/^[a-z][a-z0-9_-]{0,63}$/u.test(key)&&typeof entry=="string"&&entry.trim().length>0&&(bounded[key]=entry.trim().slice(0,256),acceptedCount+=1)}return bounded}function readMcpClientInfo(value){const clientInfo=isRuntimeRecord(value)?value:{},clientName=typeof clientInfo.name=="string"?clientInfo.name.trim():"";if(clientName.length===0)return;const optionalValues=[["version",clientInfo.version,128],["model",clientInfo.model,256],["session",clientInfo.session,256]],result={name:clientName.slice(0,128)};for(const[key,value2,limit]of optionalValues)typeof value2=="string"&&value2.trim().length>0&&(result[key]=value2.trim().slice(0,limit));const boundedProvenance=boundMcpClientProvenance(clientInfo.provenance);Object.keys(boundedProvenance).length>0&&(result.provenance=boundedProvenance);const episode=boundAgentEpisodeIdentity(clientInfo.episode,!1);return episode!==void 0&&(result.episode=episode),result}async function emitMcpChangeNotifications(action){isMutationAction(action??"")&&await Promise.all([...PM_MCP_SUBSCRIPTIONS.values()].flatMap(({registry})=>PM_MCP_RESOURCE_CONTRACTS.map(resource=>registry.emitResourceUpdated(resource.uri)))),["extension","install","package","uninstall"].includes(action??"")&&await Promise.all([...PM_MCP_SUBSCRIPTIONS.values()].map(({registry})=>registry.emitListChanged("tools"))),pruneClosedMcpSubscriptionRegistries()}async function handleToolCall(paramsInput,clientInfo,progressiveDiscoveryNegotiated=!1){const clientSignals=clientInfo?{client_info:clientInfo}:{};return runWithHarnessDetectionSignals({env:process.env,argv:process.argv,...clientSignals},async()=>{const params=asRecordClone(paramsInput),name=readRequiredString(params,"name"),handler=Object.prototype.hasOwnProperty.call(HANDLERS,name)?HANDLERS[name]:void 0;if(!handler)throw new PmCliError(`Unknown pm MCP tool: ${name}`,64);const inputResponses=params.inputResponses===void 0?void 0:parseMcpInputResponses(params.inputResponses);validateMcpToolArguments(params.arguments);const requestedArgs={...decodeHtmlEntitiesInOptions(asRecordClone(params.arguments)),...inputResponses?{inputResponses}:{},...typeof params.requestState=="string"?{requestState:params.requestState}:{}},access=await resolveMcpToolAccess(TOOLS,name,requestedArgs),requiredCustomDiscoveryEntry=progressiveDiscoveryNegotiated&&access.profile==="custom"&&name==="pm_discover";if(!access.available&&!requiredCustomDiscoveryEntry)throw new PmCliError(`pm MCP tool "${name}" is unavailable in the ${access.profile} profile.`,64);const args=await normalizeWorkspaceToolArguments(name,requestedArgs),cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),pmRoot=resolvePmRoot(cwd,typeof args.path=="string"?args.path:void 0),workspaceIdentity=await pathExists(getSettingsPath(pmRoot))?(await readSettings(pmRoot)).agent_identity:void 0;return runWithHarnessDetectionSignals({env:{...process.env,PM_PATH:pmRoot},argv:process.argv,cwd,...clientSignals},()=>runWithWorkspaceHarnessSignalDescriptors(workspaceIdentity?.harness_signals??[],async()=>{const action=resolveInvokedAction(name,args),warnings=[...detectUnexpectedTopLevelKeys(name,args,declaredToolKeys()),...detectUnexpectedOptionKeys(name,action,args),...await collectMutationGuardWarnings(name,action,args)];for(const warning of warnings)console.error(`[pm-mcp] ${warning}`);const result=await handler(args);return emitMcpChangeNotifications(action),resultContent(result,warnings,args.tokenAccounting===!0,progressiveDiscoveryNegotiated)},{probesEnabled:workspaceIdentity?.probes_enabled}))})}async function openMcpSubscription(input){if(typeof input.request.id!="string"&&typeof input.request.id!="number"||input.request.method!=="subscriptions/listen")throw new PmMcpProtocolError("Invalid MCP subscriptions/listen request",PM_MCP_ERROR_CODES.invalidParams,{required:["id","method","params.notifications"]});resolveMcpRequestContext(input.request.params);const key=input.key??input.request.id;if(PM_MCP_SUBSCRIPTIONS.has(key))throw new PmMcpProtocolError("MCP subscription id is already active",PM_MCP_ERROR_CODES.invalidParams,{subscriptionId:input.request.id});const registry=createMcpSubscriptionRegistry();await registry.open({id:input.request.id,notifications:input.request.params?.notifications,sink:input.sink}),PM_MCP_SUBSCRIPTIONS.set(key,{id:input.request.id,registry})}function closeMcpSubscription(id,key=id){const subscription=PM_MCP_SUBSCRIPTIONS.get(key);if(!(!subscription||subscription.id!==id))return PM_MCP_SUBSCRIPTIONS.delete(key),subscription.registry.close(id)}function closeStdioMcpSubscriptions(){const closed=[];for(const[key,subscription]of PM_MCP_SUBSCRIPTIONS){if(key!==subscription.id)continue;const result=closeMcpSubscription(subscription.id,key);result&&closed.push({id:subscription.id,result})}return closed}async function resolveMcpToolSchemaForRequest(request){if(request.method!=="tools/call")return;const name=request.params?.name;return typeof name!="string"?void 0:(await resolveMcpToolSurface(TOOLS,requestWorkspaceArgs(request.params))).tools.find(tool=>tool.name===name)?.inputSchema}function buildMcpToolCallErrorResult(request,error){if(request.method!=="tools/call"||error instanceof PmMcpProtocolError)return;const content=errorContent(error,hasMcpProtocolVersionMetadata(request)&&hasMcpClientExtension(resolveMcpRequestContext(request.params),PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION));return hasMcpProtocolVersionMetadata(request)?buildMcpCompleteResult(content,PM_MCP_SERVER_INFO):content}function requestWorkspaceArgs(params){const paramsRecord=asRecordClone(params);return asRecordClone(paramsRecord.arguments??paramsRecord)}async function readWorkspaceResource(uri,params){const args=requestWorkspaceArgs(params),cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),contract=PM_MCP_RESOURCE_CONTRACTS.find(resource=>resource.uri===uri);if(!contract)throw new PmCliError(`Unknown pm MCP resource: ${uri}`,64);let value;if(uri==="pm://workspace/context")value=await runMcpAction({...args,action:"context",limit:10});else if(uri==="pm://workspace/claims")value=await runMcpAction({...args,action:"list",status:"in_progress",limit:20});else if(uri==="pm://workspace/focus")value=await runMcpAction({...args,action:"focus",subcommand:"show"});else{const guidePath=path.join(cwd,"AGENTS.md");value=await pathExists(guidePath)?(await readFile(guidePath,"utf8")).slice(0,32e3):"No repository-local AGENTS.md was found."}return{contents:[{uri,mimeType:contract.mimeType,text:typeof value=="string"?value:JSON.stringify(value,null,2)}]}}async function loadRequestSkillRegistry(params){const args=requestWorkspaceArgs(params),cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),workspaceRoot=resolveWorkspaceRoot(resolvePmRoot(cwd,typeof args.path=="string"?args.path:void 0));return PmMcpSkillRegistry.load({packageRoot:resolvePmPackageRoot(),workspaceRoot,packageVersion:PM_MCP_SERVER_VERSION})}function renderWorkflowPrompt(params){const paramsRecord=asRecordClone(params),name=readRequiredString(paramsRecord,"name"),prompt=PM_MCP_PROMPT_CONTRACTS.find(candidate=>candidate.name===name);if(!prompt)throw new PmCliError(`Unknown pm MCP prompt: ${name}`,64);const argumentsRecord=asRecordClone(paramsRecord.arguments);let text=prompt.template;for(const argument of prompt.arguments){const value=argumentsRecord[argument.name];if(argument.required&&(typeof value!="string"||value.trim().length===0))throw new PmCliError(`Missing required prompt argument: ${argument.name}`,64);text=text.replaceAll(`{{${argument.name}}}`,typeof value=="string"?value:"")}return{description:prompt.description,messages:[{role:"user",content:{type:"text",text}}]}}const LEGACY_MCP_ADAPTER=new LegacyMcpAdapter({serverInfo:PM_MCP_SERVER_INFO,capabilities:PM_MCP_SERVER_CAPABILITIES,instructions:PM_MCP_INSTRUCTIONS,parseClientInfo:readMcpClientInfo,listTools:async params=>({tools:(await resolveMcpToolSurface(TOOLS,requestWorkspaceArgs(params))).tools}),callTool:handleToolCall,listResources:()=>({resources:PM_MCP_RESOURCE_CONTRACTS}),readResource:params=>readWorkspaceResource(readRequiredString(asRecordClone(params),"uri"),params),listPrompts:()=>({prompts:PM_MCP_PROMPT_CONTRACTS.map(prompt=>({name:prompt.name,description:prompt.description,arguments:prompt.arguments}))}),getPrompt:renderWorkflowPrompt});function deterministicMcpTools(tools){return tools.map(tool=>({...tool,inputSchema:validateMcpJsonSchema(tool.inputSchema)})).sort((left,right)=>left.name.localeCompare(right.name))}function mcpTaskPrincipal(requestContext){return requestContext.clientInfo?`${requestContext.clientInfo.name}@${requestContext.clientInfo.version}`:"anonymous-stdio"}function mcpTaskStore(){return createMcpTaskStore({pmRoot:resolvePmRoot(process.cwd()),owner:"pm-mcp-task-provider"})}function validateMcpToolArguments(value){if(value!==void 0&&!isMcpRecord(value))throw new PmCliError("pm MCP tool arguments must be an object.",64)}function shouldCreateMcpTask(params,requestContext){if(!hasMcpClientExtension(requestContext,PM_MCP_TASKS_EXTENSION))return!1;const requestParams=asRecordClone(params),name=requestParams.name,args=asRecordClone(requestParams.arguments);return PM_MCP_DIRECT_TASK_TOOLS.has(name)||name==="pm_test"&&(args.subcommand==="run"||isMcpRecord(args.options)&&args.options.subcommand==="run")?!0:name!=="pm_run"?!1:typeof args.action=="string"&&PM_MCP_RUN_TASK_ACTIONS.has(args.action)}const PENDING_MCP_TASKS=new Map;async function executeMcpTask(execution,inputResponses){const params={...execution.params,...inputResponses?{inputResponses}:{},...execution.requestState?{requestState:execution.requestState}:{}};try{const result=await handleToolCall(params,execution.context.clientInfo,hasMcpClientExtension(execution.context,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION));await execution.store.complete(execution.taskId,execution.principal,buildMcpCompleteResult(result,PM_MCP_SERVER_INFO)),PENDING_MCP_TASKS.delete(execution.taskId)}catch(error){if(error instanceof PmMcpInputRequiredError){execution.requestState=error.requestState,await execution.store.requireInput({taskId:execution.taskId,principal:execution.principal,requestContext:execution.context,inputRequests:error.inputRequests,statusMessage:"Task requires additional client input."});return}error instanceof PmMcpProtocolError?await execution.store.fail(execution.taskId,execution.principal,{code:error.code,message:error.message,data:error.data}):await execution.store.complete(execution.taskId,execution.principal,buildMcpCompleteResult(errorContent(error,hasMcpClientExtension(execution.context,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION)),PM_MCP_SERVER_INFO)),PENDING_MCP_TASKS.delete(execution.taskId)}}async function settleMcpTaskExecution(taskId,execution){try{await execution}catch{PENDING_MCP_TASKS.delete(taskId)}}function scheduleMcpTaskExecution(execution,inputResponses){settleMcpTaskExecution(execution.taskId,executeMcpTask(execution,inputResponses))}async function createMcpTaskForToolCall(params,requestContext){const store=mcpTaskStore(),principal=mcpTaskPrincipal(requestContext),task=await store.create({principal,statusMessage:"pm operation accepted for asynchronous execution."}),execution={context:requestContext,params:asRecordClone(params),principal,store,taskId:task.taskId};return PENDING_MCP_TASKS.set(task.taskId,execution),scheduleMcpTaskExecution(execution),attachMcpServerInfo(task,PM_MCP_SERVER_INFO)}async function dispatchMcpTaskMethod(request,requestContext){if(!hasMcpClientExtension(requestContext,PM_MCP_TASKS_EXTENSION))throw new PmMcpProtocolError("Missing required client capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:{extensions:{[PM_MCP_TASKS_EXTENSION]:{}}}});const params=asRecordClone(request.params),taskId=readRequiredString(params,"taskId"),principal=mcpTaskPrincipal(requestContext),store=mcpTaskStore();if(request.method==="tasks/get")return buildMcpCompleteResult(await store.get(taskId,principal),PM_MCP_SERVER_INFO);if(request.method==="tasks/update"){const update=await store.update(taskId,principal,params.inputResponses),execution=PENDING_MCP_TASKS.get(taskId);return execution&&update.acceptedKeys.length>0&&update.remainingKeys.length===0&&scheduleMcpTaskExecution(execution,await store.takeInputResponses(taskId,principal)),buildMcpCompleteResult({},PM_MCP_SERVER_INFO)}return await store.cancel(taskId,principal),PENDING_MCP_TASKS.delete(taskId),buildMcpCompleteResult({},PM_MCP_SERVER_INFO)}async function dispatchModernToolMethod(request,requestContext,clientInfo){if(request.method==="tools/list"){const surface=await resolveMcpToolSurface(TOOLS,requestWorkspaceArgs(request.params)),listedTools=hasMcpClientExtension(requestContext,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION)?[...surface.tools.filter(tool=>PM_MCP_ENTRY_TOOL_NAMES.includes(tool.name)),...surface.profile==="custom"&&!surface.tools.some(tool=>tool.name==="pm_discover")?TOOLS.filter(tool=>tool.name==="pm_discover"):[]]:surface.tools;return buildMcpCompleteResult(withMcpCachePolicy({tools:hasCompatiblePmMcpAppsCapability(requestContext)?decoratePmMcpToolsWithApps(deterministicMcpTools(listedTools)):deterministicMcpTools(listedTools)},PM_MCP_CACHE_POLICIES.tools),PM_MCP_SERVER_INFO)}if(validateMcpToolArguments(request.params?.arguments),shouldCreateMcpTask(request.params,requestContext))return createMcpTaskForToolCall(request.params,requestContext);try{return buildMcpCompleteResult(await handleToolCall(request.params,clientInfo,hasMcpClientExtension(requestContext,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION)),PM_MCP_SERVER_INFO)}catch(error){if(!(error instanceof PmMcpInputRequiredError))throw error;return buildMcpInputRequiredResult({requestContext,serverInfo:PM_MCP_SERVER_INFO,inputRequests:error.inputRequests,requestState:error.requestState})}}async function dispatchModernResourceMethod(request,requestContext){if(request.method==="resources/list"){const resources=[...PM_MCP_RESOURCE_CONTRACTS,...hasCompatiblePmMcpAppsCapability(requestContext)?PM_MCP_APP_CONTRACTS.map(contract=>({uri:contract.uri,name:contract.name,description:contract.description,mimeType:PM_MCP_APP_MIME_TYPE,_meta:{ui:contract.resourceMeta}})):[]].sort((left,right)=>left.uri.localeCompare(right.uri));return buildMcpCompleteResult(withMcpCachePolicy({resources},PM_MCP_CACHE_POLICIES.resources),PM_MCP_SERVER_INFO)}if(request.method==="resources/templates/list")return buildMcpCompleteResult(withMcpCachePolicy({resourceTemplates:[]},PM_MCP_CACHE_POLICIES.resources),PM_MCP_SERVER_INFO);try{const uri=readRequiredString(asRecordClone(request.params),"uri"),app=findPmMcpAppByUri(uri);let resource;if(app){if(!hasPmMcpAppsCapability(requestContext))throw new PmMcpProtocolError("MCP App resource requires negotiated client capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:{extensions:{[PM_MCP_APPS_EXTENSION]:PM_MCP_APPS_SERVER_CAPABILITY}}});resource={contents:[{uri,mimeType:PM_MCP_APP_MIME_TYPE,text:renderPmMcpAppHtml(app),_meta:{ui:app.resourceMeta}}]}}else uri.startsWith("skill://")?(assertPmMcpSkillsCapability(requestContext),resource={...(await loadRequestSkillRegistry(request.params)).read(uri)}):resource=await readWorkspaceResource(uri,request.params);return buildMcpCompleteResult(withMcpCachePolicy(resource,PM_MCP_CACHE_POLICIES.resource),PM_MCP_SERVER_INFO)}catch(error){throw!(error instanceof PmCliError)||!error.message.startsWith("Unknown pm MCP resource:")?error:new PmMcpProtocolError(error.message,PM_MCP_ERROR_CODES.invalidParams,{field:"uri"})}}function hasCompatiblePmMcpAppsCapability(requestContext){try{return hasPmMcpAppsCapability(requestContext)}catch(error){if(error instanceof PmMcpProtocolError)return!1;throw error}}function readSkillPageOptions(params){if(params.cursor!==void 0&&typeof params.cursor!="string")throw new PmMcpProtocolError("Skills cursor must be a string",PM_MCP_ERROR_CODES.invalidParams,{field:"cursor"});if(params.limit!==void 0&&typeof params.limit!="number")throw new PmMcpProtocolError("Skills limit must be a number",PM_MCP_ERROR_CODES.invalidParams,{field:"limit"});return{...typeof params.cursor=="string"?{cursor:params.cursor}:{},...typeof params.limit=="number"?{limit:params.limit}:{}}}async function dispatchModernSkillMethod(request,requestContext){const directoryRead=request.method==="resources/directory/read";assertPmMcpSkillsCapability(requestContext,directoryRead);const params=asRecordClone(request.params),registry=await loadRequestSkillRegistry(request.params);let result;return request.method==="skills/list"?result={...registry.list(readSkillPageOptions(params))}:request.method==="skills/get"?result={skill:registry.get(readRequiredString(params,"uri"))}:result={...registry.readDirectory(readRequiredString(params,"uri"),readSkillPageOptions(params))},buildMcpCompleteResult(withMcpCachePolicy(result,PM_MCP_CACHE_POLICIES.resource),PM_MCP_SERVER_INFO)}function dispatchModernPromptMethod(request){const result=request.method==="prompts/list"?withMcpCachePolicy({prompts:PM_MCP_PROMPT_CONTRACTS.map(prompt=>({name:prompt.name,description:prompt.description,arguments:prompt.arguments})).sort((left,right)=>left.name.localeCompare(right.name))},PM_MCP_CACHE_POLICIES.prompts):renderWorkflowPrompt(request.params);return buildMcpCompleteResult(result,PM_MCP_SERVER_INFO)}async function dispatchModernMcpRequest(request,meta){const requestContext=resolveMcpRequestContext(request.params),clientInfo=readMcpClientInfo(meta[PM_MCP_META_KEYS.clientInfo]);if(request.method==="server/discover")return buildMcpDiscoverResult({serverInfo:PM_MCP_SERVER_INFO,capabilities:PM_MCP_SERVER_CAPABILITIES,instructions:PM_MCP_INSTRUCTIONS});if(request.method==="ping")throw new PmMcpProtocolError("MCP method not found: ping",-32601,{removedIn:PM_MCP_PROTOCOL_VERSION});if(PM_MCP_SKILL_METHODS.has(request.method??""))return dispatchModernSkillMethod(request,requestContext);if(request.method==="tasks/get"||request.method==="tasks/update"||request.method==="tasks/cancel")return dispatchMcpTaskMethod(request,requestContext);if(request.method==="tools/list"||request.method==="tools/call")return dispatchModernToolMethod(request,requestContext,clientInfo);if(request.method==="resources/list"||request.method==="resources/templates/list"||request.method==="resources/read")return dispatchModernResourceMethod(request,requestContext);if(request.method==="prompts/list"||request.method==="prompts/get")return dispatchModernPromptMethod(request);throw new PmMcpProtocolError(`MCP method not found: ${request.method??"(missing)"}`,-32601)}async function handleRequestInReproducibleContext(request){if(!(!request.id&&request.method?.startsWith("notifications/"))){if(hasMcpProtocolVersionMetadata(request)){const allowlist=(process.env.PM_MCP_BAGGAGE_ALLOWLIST??"").split(",").map(entry=>entry.trim()).filter(Boolean);return runWithMcpTraceContext(extractMcpTraceContext(request.params,{baggageAllowlist:allowlist}),()=>dispatchModernMcpRequest(request,request.params._meta))}return request.method==="initialize"?LEGACY_MCP_ADAPTER.initialize(request.params):LEGACY_MCP_ADAPTER.dispatch(request)}}function hasMcpProtocolVersionMetadata(request){const meta=isMcpRecord(request.params)?request.params._meta:void 0;return isMcpRecord(meta)&&Object.prototype.hasOwnProperty.call(meta,PM_MCP_META_KEYS.protocolVersion)}async function handleRequest(request){return runWithReproducibleProcessEnvironment(process.env,()=>handleRequestInReproducibleContext(request))}function writeResponse(id,payload){process.stdout.write(`${JSON.stringify({jsonrpc:"2.0",id,result:payload})}
|
|
2
|
+
(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]="fe904212-6429-55c9-9d7b-39d7e2850fed")}catch{}})();import{realpathSync}from"node:fs";import{readFile}from"node:fs/promises";import path from"node:path";import readline from"node:readline";import{fileURLToPath}from"node:url";import{resolvePmCliVersion,EXIT_CODE,PmCliError,decodeHtmlEntitiesInOptions,levenshteinDistanceWithinLimit,asRecordClone,createSerialQueue,evaluateMutationGuard,getSettingsPath,isMutationAction,pathExists,readSettings,runWithHarnessDetectionSignals,runWithWorkspaceHarnessSignalDescriptors,boundAgentEpisodeIdentity}from"../sdk/runtime-primitives.js";import{pmToolActionNestedOptionKeys}from"../sdk/cli-contracts/tool-schema.js";import{readRequiredString,runAction,runWithActiveExtensions}from"../sdk/runtime.js";import{NARROW_TOOL_ACTIONS,TOOLS}from"./tool-definitions.js";import{normalizeWorkspaceToolArguments,resolveMcpToolAccess,resolveMcpToolSurface}from"./runtime-capabilities.js";import{PM_MCP_PROMPT_CONTRACTS,PM_MCP_RESOURCE_CONTRACTS}from"../sdk/agent-capability-contracts.js";import{PM_MCP_ENTRY_TOOL_NAMES,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION,PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY,discoverPmTools,parsePmToolDiscoveryOptions}from"../sdk/mcp/discovery.js";import{commitItemMutations}from"../sdk/item-transaction.js";import{isRuntimeRecord,markMcpMutationTransportInput}from"../sdk/runtime-input.js";import{attachOutputTokenAccounting}from"../sdk/output-token-accounting.js";import{createReproducibleProcessRunner,runWithReproducibleProcessEnvironment}from"../sdk/reproducibility/process.js";import{parseAtomicMutationControls}from"../sdk/structured-mutations.js";import{planItemMutationDocument,previewItemMutationDocument}from"../sdk/lifecycle/structured-mutation-plan.js";import{resolveAuthor,resolvePmRoot,resolveWorkspaceRoot}from"../sdk/runtime-primitives.js";import{PM_MCP_ERROR_CODES,PM_MCP_META_KEYS,PM_MCP_PROTOCOL_VERSION,PmMcpProtocolError,attachMcpServerInfo,buildMcpCompleteResult,buildMcpDiscoverResult,hasMcpClientExtension,isMcpRecord,resolveMcpRequestContext}from"../sdk/mcp/protocol.js";import{PmMcpInputRequiredError,buildMcpInputRequiredResult,parseMcpInputResponses,validateMcpJsonSchema,withMcpCachePolicy}from"../sdk/mcp/interactions.js";import{PM_MCP_TASKS_EXTENSION,createMcpTaskStore}from"../sdk/mcp/tasks.js";import{PmMcpSubscriptionRegistry}from"../sdk/mcp/subscriptions.js";import{extractMcpTraceContext,runWithMcpTraceContext}from"../sdk/mcp/authorization.js";import{LegacyMcpAdapter}from"./legacy-adapter.js";import{PM_MCP_APP_CONTRACTS,PM_MCP_APP_MIME_TYPE,PM_MCP_APPS_EXTENSION,PM_MCP_APPS_SERVER_CAPABILITY,decoratePmMcpToolsWithApps,findPmMcpAppByUri,hasPmMcpAppsCapability,renderPmMcpAppHtml}from"../sdk/mcp/apps.js";import{PM_MCP_SKILLS_EXTENSION,PM_MCP_SKILLS_SERVER_CAPABILITY,PmMcpSkillRegistry,assertPmMcpSkillsCapability}from"../sdk/mcp/skills.js";function runMcpAction(args){return runAction(markMcpMutationTransportInput(args))}const PM_PACKAGE_ROOT_ENV="PM_CLI_PACKAGE_ROOT";function resolvePmPackageRoot(){return fileURLToPath(new URL("../..",import.meta.url))}(typeof process.env[PM_PACKAGE_ROOT_ENV]!="string"||process.env[PM_PACKAGE_ROOT_ENV]?.trim().length===0)&&(process.env[PM_PACKAGE_ROOT_ENV]=resolvePmPackageRoot());const PM_MCP_SERVER_VERSION=resolvePmCliVersion(import.meta.url,["../.."])??"0.0.0",PM_MCP_SERVER_INFO={name:"pm-mcp",version:PM_MCP_SERVER_VERSION,description:"Stateless project-context management through pm SDK contracts.",websiteUrl:"https://github.com/unbraind/pm-cli"},PM_MCP_SERVER_CAPABILITIES={prompts:{listChanged:!0},resources:{listChanged:!0,subscribe:!0},tools:{listChanged:!0},extensions:{[PM_MCP_TASKS_EXTENSION]:{},[PM_MCP_APPS_EXTENSION]:PM_MCP_APPS_SERVER_CAPABILITY,[PM_MCP_SKILLS_EXTENSION]:PM_MCP_SKILLS_SERVER_CAPABILITY,[PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION]:PM_MCP_PROGRESSIVE_DISCOVERY_SERVER_CAPABILITY}},PM_MCP_SUBSCRIPTIONS=new Map;function createMcpSubscriptionRegistry(){return new PmMcpSubscriptionRegistry({capabilities:PM_MCP_SERVER_CAPABILITIES,serverInfo:PM_MCP_SERVER_INFO})}function pruneClosedMcpSubscriptionRegistries(){for(const[key,subscription]of PM_MCP_SUBSCRIPTIONS)subscription.registry.size===0&&PM_MCP_SUBSCRIPTIONS.delete(key)}const PM_MCP_CACHE_POLICIES={prompts:{ttlMs:6e4,cacheScope:"public"},resource:{ttlMs:0,cacheScope:"private"},resources:{ttlMs:6e4,cacheScope:"public"},tools:{ttlMs:3e4,cacheScope:"private"}},PM_MCP_DIRECT_TASK_TOOLS=new Set(["pm_graph","pm_health","pm_validate"]),PM_MCP_RUN_TASK_ACTIONS=new Set(["graph","health","import","reindex","test-all","validate"]),PM_MCP_SKILL_METHODS=new Set(["skills/list","skills/get","resources/directory/read"]),PM_MCP_INSTRUCTIONS="You have access to native pm CLI tools for git-based project management. When progressive discovery is negotiated, use pm_discover to expand the small entry catalog by intent and request schemas only when needed. Use pm_next to pick the next actionable item, or pm_context or pm_search before creating new work. Prefer narrow tools (pm_next, pm_context, pm_list, pm_get, pm_search, pm_events, pm_create, pm_mutate, pm_copy, pm_focus, pm_update, pm_append, pm_claim, pm_release, pm_close, pm_comments, pm_files, pm_docs, pm_notes, pm_learnings, pm_deps, pm_graph, pm_test, pm_validate, pm_health, pm_contracts, pm_schema, pm_profile, pm_config, pm_plan) over pm_run when they cover the operation. Use pm_plan for agent harness Plan workflows: it provides Codex/Claude/Cursor-style planning with durable steps, dependencies, decisions, discoveries, validation, and materialization. Use pm_schema and pm_config for workspace configuration: pm_schema manages custom item types/statuses and pm_config reads or writes settings keys. Use pm_run with an explicit action for active package-owned operations, plus activity, aggregate, history, stats, test-all, and gc. Use history-redact for audited history-stream redaction workflows, history-repair to re-anchor a drifted history chain, and history-compact to checkpoint/prune long history streams while preserving replay integrity. Agent harness and model provenance are detected automatically; pass author only for an intentional identity override. Do not pass path during real repository tracking \u2014 only pass path for sandbox or test runs.";function declaredToolKeys(tools=TOOLS){return new Map(tools.map(tool=>{const properties=tool.inputSchema.properties??{};return[tool.name,Object.keys(properties)]}))}function nearestDeclaredKey(unexpected,declared){const limit=Math.max(1,Math.min(3,Math.floor(unexpected.length/4)+1));let best;for(const candidate of declared){const distance=levenshteinDistanceWithinLimit(unexpected,candidate,limit);distance!==null&&(best===void 0||distance<best.distance)&&(best={key:candidate,distance})}return best?.key}const UNEXPECTED_KEY_WARNING_EXEMPT_TOOLS=new Set(["pm_run"]),MCP_RETRY_ARGUMENT_KEYS=new Set(["inputResponses","requestState"]);function resolveMcpDiscoveryCursorIntegrityKey(){const configuredKey=process.env.PM_MCP_DISCOVERY_CURSOR_KEY;if(configuredKey===void 0)return;const key=Buffer.from(configuredKey,"utf8");if(key.byteLength<32)throw new PmCliError("PM_MCP_DISCOVERY_CURSOR_KEY must contain at least 32 UTF-8 bytes.",64);return key}function detectUnexpectedTopLevelKeys(toolName,args,toolDeclaredKeys=declaredToolKeys()){if(typeof args!="object"||args===null||Array.isArray(args))return[];if(UNEXPECTED_KEY_WARNING_EXEMPT_TOOLS.has(toolName))return[];const declared=toolDeclaredKeys.get(toolName);if(declared===void 0)return[];const declaredSet=new Set([...declared,...MCP_RETRY_ARGUMENT_KEYS]),warnings=[];for(const key of Object.keys(args)){if(declaredSet.has(key))continue;const suggestion=nearestDeclaredKey(key,declared);warnings.push(suggestion!==void 0?`Unexpected top-level argument "${key}" for ${toolName} (did you mean "${suggestion}"?). It is not declared and may be ignored; declared arguments are: ${declared.join(", ")}.`:`Unexpected top-level argument "${key}" for ${toolName}. It is not declared and may be ignored; declared arguments are: ${declared.join(", ")}.`)}return warnings}const HANDLERS={pm_run:args=>runMcpAction(args),pm_discover:async args=>{const surface=await resolveMcpToolSurface(TOOLS,args),cursorIntegrityKey=resolveMcpDiscoveryCursorIntegrityKey(),discoveryOptions=parsePmToolDiscoveryOptions(args);return discoverPmTools(surface.tools.map(tool=>({name:tool.name,description:tool.description,inputSchema:tool.inputSchema,authorized:!0,signals:{freshness:1,usage:PM_MCP_ENTRY_TOOL_NAMES.includes(tool.name)?1:0}})),{...discoveryOptions,profile:surface.profile,...cursorIntegrityKey===void 0?{}:{cursorIntegrityKey}})},pm_mutate:async args=>{if(!Array.isArray(args.mutations)||args.mutations.length===0)throw new PmCliError("pm_mutate requires a non-empty mutations array.",EXIT_CODE.USAGE);const explicitTransactionId=args.transactionId===void 0?void 0:readRequiredString(args,"transactionId"),upsertKey=args.upsertKey===void 0?void 0:readRequiredString(args,"upsertKey"),controls=parseAtomicMutationControls(args),cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),pmRoot=resolvePmRoot(cwd,typeof args.path=="string"?args.path:void 0),extensionScope={cwd:typeof args.cwd=="string"?args.cwd:void 0,path:pmRoot,noExtensions:args.noExtensions===!0},plan=await runWithActiveExtensions(extensionScope,()=>planItemMutationDocument({pmRoot,input:JSON.stringify({schema_version:1,mutations:args.mutations}),...explicitTransactionId===void 0?{}:{transactionId:explicitTransactionId},...upsertKey===void 0?{}:{upsertKey}})),{mutations,references,rows}=plan,transactionId=plan.transaction_id,receipt={transaction_id:transactionId,transaction_id_source:plan.transaction_id_source,...plan.upsert_key===void 0?{}:{upsert_key:plan.upsert_key}};if(args.dryRun===!0){const preview=await runWithActiveExtensions(extensionScope,()=>previewItemMutationDocument({pmRoot,author:resolveAuthor(typeof args.author=="string"?args.author:void 0,"unknown"),plan}));return{...receipt,dry_run:!0,validation:preview.validation,mutation_count:mutations.length,mutations,references,rows:preview.rows}}const result=await runWithActiveExtensions(extensionScope,()=>commitItemMutations({pmRoot,transactionId,author:resolveAuthor(typeof args.author=="string"?args.author:void 0,"unknown"),mutations,...controls}));return{...Object.fromEntries(Object.entries(result).filter(([key])=>key!=="transactionId")),...receipt,mutation_count:mutations.length,references,rows}},...Object.fromEntries(Object.entries(NARROW_TOOL_ACTIONS).map(([tool,action])=>[tool,args=>runMcpAction({...args,action})]))};function resolveInvokedAction(toolName,args){return toolName==="pm_run"?typeof args.action=="string"?args.action:void 0:NARROW_TOOL_ACTIONS[toolName]}async function collectMutationGuardWarnings(toolName,action,args){if(toolName!=="pm_mutate"&&!isMutationAction(action??""))return[];const cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),pmRoot=resolvePmRoot(cwd,typeof args.path=="string"?args.path:void 0);if(!await pathExists(getSettingsPath(pmRoot)))return[];const settings=await readSettings(pmRoot),nestedOptions=typeof args.options=="object"&&args.options!==null&&!Array.isArray(args.options)?args.options:{};return evaluateMutationGuard({author:resolveAuthor(typeof args.author=="string"?args.author:typeof nestedOptions.author=="string"?nestedOptions.author:void 0,settings.author_default),payload:Object.fromEntries(Object.entries(args).filter(([key])=>key!=="cwd"&&key!=="path")),settings:settings.mutation_guard,force:args.force===!0||nestedOptions.force===!0}).warnings}function detectUnexpectedOptionKeys(toolName,action,args){const options=args.options;if(action===void 0||typeof options!="object"||options===null||Array.isArray(options))return[];const declared=pmToolActionNestedOptionKeys(action);if(declared===void 0)return[];const declaredSet=new Set(declared),warnings=[];for(const key of Object.keys(options)){if(declaredSet.has(key))continue;const suggestion=nearestDeclaredKey(key,declared);warnings.push(suggestion!==void 0?`Unknown option "${key}" for ${toolName} action "${action}" (did you mean "${suggestion}"?). The ${action} contract does not read it, so it has no effect; declared keys are: ${declared.join(", ")}.`:`Unknown option "${key}" for ${toolName} action "${action}". The ${action} contract does not read it, so it has no effect; declared keys are: ${declared.join(", ")}.`)}return warnings}function resultContent(result,warnings,tokenAccounting=!1,canonicalStructuredResult=!1){const effectiveResult=tokenAccounting?attachOutputTokenAccounting(result,value=>JSON.stringify(value,null,2)):result,structuredContent=warnings!==void 0&&warnings.length>0?{result:effectiveResult,warnings}:{result:effectiveResult};return{content:[{type:"text",text:canonicalStructuredResult?"Canonical result: structuredContent.result":JSON.stringify(effectiveResult,null,2)}],structuredContent}}function errorContent(error,canonicalStructuredResult=!1){const code=error instanceof PmCliError?error.exitCode:1,message=error instanceof Error?error.message:String(error),details=error instanceof PmCliError?error.context:void 0;return{isError:!0,content:[{type:"text",text:canonicalStructuredResult?"Canonical error: structuredContent":JSON.stringify({error:message,code,details},null,2)}],structuredContent:{result:null,error:message,code,details}}}function boundMcpClientProvenance(value){const provenance=isRuntimeRecord(value)?value:{},bounded={};let acceptedCount=0;for(const key in provenance){if(acceptedCount>=32)break;if(!Object.prototype.hasOwnProperty.call(provenance,key))continue;const entry=provenance[key];/^[a-z][a-z0-9_-]{0,63}$/u.test(key)&&typeof entry=="string"&&entry.trim().length>0&&(bounded[key]=entry.trim().slice(0,256),acceptedCount+=1)}return bounded}function readMcpClientInfo(value){const clientInfo=isRuntimeRecord(value)?value:{},clientName=typeof clientInfo.name=="string"?clientInfo.name.trim():"";if(clientName.length===0)return;const optionalValues=[["version",clientInfo.version,128],["model",clientInfo.model,256],["session",clientInfo.session,256]],result={name:clientName.slice(0,128)};for(const[key,value2,limit]of optionalValues)typeof value2=="string"&&value2.trim().length>0&&(result[key]=value2.trim().slice(0,limit));const boundedProvenance=boundMcpClientProvenance(clientInfo.provenance);Object.keys(boundedProvenance).length>0&&(result.provenance=boundedProvenance);const episode=boundAgentEpisodeIdentity(clientInfo.episode,!1);return episode!==void 0&&(result.episode=episode),result}async function emitMcpChangeNotifications(action){isMutationAction(action??"")&&await Promise.all([...PM_MCP_SUBSCRIPTIONS.values()].flatMap(({registry})=>PM_MCP_RESOURCE_CONTRACTS.map(resource=>registry.emitResourceUpdated(resource.uri)))),["extension","install","package","uninstall"].includes(action??"")&&await Promise.all([...PM_MCP_SUBSCRIPTIONS.values()].map(({registry})=>registry.emitListChanged("tools"))),pruneClosedMcpSubscriptionRegistries()}async function handleToolCall(paramsInput,clientInfo,progressiveDiscoveryNegotiated=!1){const clientSignals=clientInfo?{client_info:clientInfo}:{};return runWithHarnessDetectionSignals({env:process.env,argv:process.argv,...clientSignals},async()=>{const params=asRecordClone(paramsInput),name=readRequiredString(params,"name"),handler=Object.prototype.hasOwnProperty.call(HANDLERS,name)?HANDLERS[name]:void 0;if(!handler)throw new PmCliError(`Unknown pm MCP tool: ${name}`,64);const inputResponses=params.inputResponses===void 0?void 0:parseMcpInputResponses(params.inputResponses);validateMcpToolArguments(params.arguments);const requestedArgs={...decodeHtmlEntitiesInOptions(asRecordClone(params.arguments)),...inputResponses?{inputResponses}:{},...typeof params.requestState=="string"?{requestState:params.requestState}:{}},access=await resolveMcpToolAccess(TOOLS,name,requestedArgs),requiredCustomDiscoveryEntry=progressiveDiscoveryNegotiated&&access.profile==="custom"&&name==="pm_discover";if(!access.available&&!requiredCustomDiscoveryEntry)throw new PmCliError(`pm MCP tool "${name}" is unavailable in the ${access.profile} profile.`,64);const args=await normalizeWorkspaceToolArguments(name,requestedArgs),cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),pmRoot=resolvePmRoot(cwd,typeof args.path=="string"?args.path:void 0),workspaceIdentity=await pathExists(getSettingsPath(pmRoot))?(await readSettings(pmRoot)).agent_identity:void 0;return runWithHarnessDetectionSignals({env:{...process.env,PM_PATH:pmRoot},argv:process.argv,cwd,...clientSignals},()=>runWithWorkspaceHarnessSignalDescriptors(workspaceIdentity?.harness_signals??[],async()=>{const action=resolveInvokedAction(name,args),warnings=[...detectUnexpectedTopLevelKeys(name,args,declaredToolKeys()),...detectUnexpectedOptionKeys(name,action,args),...await collectMutationGuardWarnings(name,action,args)];for(const warning of warnings)console.error(`[pm-mcp] ${warning}`);const result=await handler(args);return emitMcpChangeNotifications(action),resultContent(result,warnings,args.tokenAccounting===!0,progressiveDiscoveryNegotiated)},{probesEnabled:workspaceIdentity?.probes_enabled}))})}async function openMcpSubscription(input){if(typeof input.request.id!="string"&&typeof input.request.id!="number"||input.request.method!=="subscriptions/listen")throw new PmMcpProtocolError("Invalid MCP subscriptions/listen request",PM_MCP_ERROR_CODES.invalidParams,{required:["id","method","params.notifications"]});resolveMcpRequestContext(input.request.params);const key=input.key??input.request.id;if(PM_MCP_SUBSCRIPTIONS.has(key))throw new PmMcpProtocolError("MCP subscription id is already active",PM_MCP_ERROR_CODES.invalidParams,{subscriptionId:input.request.id});const registry=createMcpSubscriptionRegistry();await registry.open({id:input.request.id,notifications:input.request.params?.notifications,sink:input.sink}),PM_MCP_SUBSCRIPTIONS.set(key,{id:input.request.id,registry})}function closeMcpSubscription(id,key=id){const subscription=PM_MCP_SUBSCRIPTIONS.get(key);if(!(!subscription||subscription.id!==id))return PM_MCP_SUBSCRIPTIONS.delete(key),subscription.registry.close(id)}function closeStdioMcpSubscriptions(){const closed=[];for(const[key,subscription]of PM_MCP_SUBSCRIPTIONS){if(key!==subscription.id)continue;const result=closeMcpSubscription(subscription.id,key);result&&closed.push({id:subscription.id,result})}return closed}async function resolveMcpToolSchemaForRequest(request){if(request.method!=="tools/call")return;const name=request.params?.name;return typeof name!="string"?void 0:(await resolveMcpToolSurface(TOOLS,requestWorkspaceArgs(request.params))).tools.find(tool=>tool.name===name)?.inputSchema}function buildMcpToolCallErrorResult(request,error){if(request.method!=="tools/call"||error instanceof PmMcpProtocolError)return;const content=errorContent(error,hasMcpProtocolVersionMetadata(request)&&hasMcpClientExtension(resolveMcpRequestContext(request.params),PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION));return hasMcpProtocolVersionMetadata(request)?buildMcpCompleteResult(content,PM_MCP_SERVER_INFO):content}function requestWorkspaceArgs(params){const paramsRecord=asRecordClone(params);return asRecordClone(paramsRecord.arguments??paramsRecord)}async function readWorkspaceResource(uri,params){const args=requestWorkspaceArgs(params),cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),contract=PM_MCP_RESOURCE_CONTRACTS.find(resource=>resource.uri===uri);if(!contract)throw new PmCliError(`Unknown pm MCP resource: ${uri}`,64);let value;if(uri==="pm://workspace/context")value=await runMcpAction({...args,action:"context",limit:10});else if(uri==="pm://workspace/claims")value=await runMcpAction({...args,action:"list",status:"in_progress",limit:20});else if(uri==="pm://workspace/focus")value=await runMcpAction({...args,action:"focus",subcommand:"show"});else{const guidePath=path.join(cwd,"AGENTS.md");value=await pathExists(guidePath)?(await readFile(guidePath,"utf8")).slice(0,32e3):"No repository-local AGENTS.md was found."}return{contents:[{uri,mimeType:contract.mimeType,text:typeof value=="string"?value:JSON.stringify(value,null,2)}]}}async function loadRequestSkillRegistry(params){const args=requestWorkspaceArgs(params),cwd=typeof args.cwd=="string"?args.cwd:process.cwd(),workspaceRoot=resolveWorkspaceRoot(resolvePmRoot(cwd,typeof args.path=="string"?args.path:void 0));return PmMcpSkillRegistry.load({packageRoot:resolvePmPackageRoot(),workspaceRoot,packageVersion:PM_MCP_SERVER_VERSION})}function renderWorkflowPrompt(params){const paramsRecord=asRecordClone(params),name=readRequiredString(paramsRecord,"name"),prompt=PM_MCP_PROMPT_CONTRACTS.find(candidate=>candidate.name===name);if(!prompt)throw new PmCliError(`Unknown pm MCP prompt: ${name}`,64);const argumentsRecord=asRecordClone(paramsRecord.arguments);let text=prompt.template;for(const argument of prompt.arguments){const value=argumentsRecord[argument.name];if(argument.required&&(typeof value!="string"||value.trim().length===0))throw new PmCliError(`Missing required prompt argument: ${argument.name}`,64);text=text.replaceAll(`{{${argument.name}}}`,typeof value=="string"?value:"")}return{description:prompt.description,messages:[{role:"user",content:{type:"text",text}}]}}const LEGACY_MCP_ADAPTER=new LegacyMcpAdapter({serverInfo:PM_MCP_SERVER_INFO,capabilities:PM_MCP_SERVER_CAPABILITIES,instructions:PM_MCP_INSTRUCTIONS,parseClientInfo:readMcpClientInfo,listTools:async params=>({tools:(await resolveMcpToolSurface(TOOLS,requestWorkspaceArgs(params))).tools}),callTool:handleToolCall,listResources:()=>({resources:PM_MCP_RESOURCE_CONTRACTS}),readResource:params=>readWorkspaceResource(readRequiredString(asRecordClone(params),"uri"),params),listPrompts:()=>({prompts:PM_MCP_PROMPT_CONTRACTS.map(prompt=>({name:prompt.name,description:prompt.description,arguments:prompt.arguments}))}),getPrompt:renderWorkflowPrompt});function deterministicMcpTools(tools){return tools.map(tool=>({...tool,inputSchema:validateMcpJsonSchema(tool.inputSchema)})).sort((left,right)=>left.name.localeCompare(right.name))}function mcpTaskPrincipal(requestContext){return requestContext.clientInfo?`${requestContext.clientInfo.name}@${requestContext.clientInfo.version}`:"anonymous-stdio"}function mcpTaskStore(){return createMcpTaskStore({pmRoot:resolvePmRoot(process.cwd()),owner:"pm-mcp-task-provider"})}function validateMcpToolArguments(value){if(value!==void 0&&!isMcpRecord(value))throw new PmCliError("pm MCP tool arguments must be an object.",64)}function shouldCreateMcpTask(params,requestContext){if(!hasMcpClientExtension(requestContext,PM_MCP_TASKS_EXTENSION))return!1;const requestParams=asRecordClone(params),name=requestParams.name,args=asRecordClone(requestParams.arguments);return PM_MCP_DIRECT_TASK_TOOLS.has(name)||name==="pm_test"&&(args.subcommand==="run"||isMcpRecord(args.options)&&args.options.subcommand==="run")?!0:name!=="pm_run"?!1:typeof args.action=="string"&&PM_MCP_RUN_TASK_ACTIONS.has(args.action)}const PENDING_MCP_TASKS=new Map;async function executeMcpTask(execution,inputResponses){const params={...execution.params,...inputResponses?{inputResponses}:{},...execution.requestState?{requestState:execution.requestState}:{}};try{const result=await handleToolCall(params,execution.context.clientInfo,hasMcpClientExtension(execution.context,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION));await execution.store.complete(execution.taskId,execution.principal,buildMcpCompleteResult(result,PM_MCP_SERVER_INFO)),PENDING_MCP_TASKS.delete(execution.taskId)}catch(error){if(error instanceof PmMcpInputRequiredError){execution.requestState=error.requestState,await execution.store.requireInput({taskId:execution.taskId,principal:execution.principal,requestContext:execution.context,inputRequests:error.inputRequests,statusMessage:"Task requires additional client input."});return}error instanceof PmMcpProtocolError?await execution.store.fail(execution.taskId,execution.principal,{code:error.code,message:error.message,data:error.data}):await execution.store.complete(execution.taskId,execution.principal,buildMcpCompleteResult(errorContent(error,hasMcpClientExtension(execution.context,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION)),PM_MCP_SERVER_INFO)),PENDING_MCP_TASKS.delete(execution.taskId)}}async function settleMcpTaskExecution(taskId,execution){try{await execution}catch{PENDING_MCP_TASKS.delete(taskId)}}function scheduleMcpTaskExecution(execution,inputResponses){settleMcpTaskExecution(execution.taskId,executeMcpTask(execution,inputResponses))}async function createMcpTaskForToolCall(params,requestContext){const store=mcpTaskStore(),principal=mcpTaskPrincipal(requestContext),task=await store.create({principal,statusMessage:"pm operation accepted for asynchronous execution."}),execution={context:requestContext,params:asRecordClone(params),principal,store,taskId:task.taskId};return PENDING_MCP_TASKS.set(task.taskId,execution),scheduleMcpTaskExecution(execution),attachMcpServerInfo(task,PM_MCP_SERVER_INFO)}async function dispatchMcpTaskMethod(request,requestContext){if(!hasMcpClientExtension(requestContext,PM_MCP_TASKS_EXTENSION))throw new PmMcpProtocolError("Missing required client capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:{extensions:{[PM_MCP_TASKS_EXTENSION]:{}}}});const params=asRecordClone(request.params),taskId=readRequiredString(params,"taskId"),principal=mcpTaskPrincipal(requestContext),store=mcpTaskStore();if(request.method==="tasks/get")return buildMcpCompleteResult(await store.get(taskId,principal),PM_MCP_SERVER_INFO);if(request.method==="tasks/update"){const update=await store.update(taskId,principal,params.inputResponses),execution=PENDING_MCP_TASKS.get(taskId);return execution&&update.acceptedKeys.length>0&&update.remainingKeys.length===0&&scheduleMcpTaskExecution(execution,await store.takeInputResponses(taskId,principal)),buildMcpCompleteResult({},PM_MCP_SERVER_INFO)}return await store.cancel(taskId,principal),PENDING_MCP_TASKS.delete(taskId),buildMcpCompleteResult({},PM_MCP_SERVER_INFO)}async function dispatchModernToolMethod(request,requestContext,clientInfo){if(request.method==="tools/list"){const surface=await resolveMcpToolSurface(TOOLS,requestWorkspaceArgs(request.params)),listedTools=hasMcpClientExtension(requestContext,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION)?[...surface.tools.filter(tool=>PM_MCP_ENTRY_TOOL_NAMES.includes(tool.name)),...surface.profile==="custom"&&!surface.tools.some(tool=>tool.name==="pm_discover")?TOOLS.filter(tool=>tool.name==="pm_discover"):[]]:surface.tools;return buildMcpCompleteResult(withMcpCachePolicy({tools:hasCompatiblePmMcpAppsCapability(requestContext)?decoratePmMcpToolsWithApps(deterministicMcpTools(listedTools)):deterministicMcpTools(listedTools)},PM_MCP_CACHE_POLICIES.tools),PM_MCP_SERVER_INFO)}if(validateMcpToolArguments(request.params?.arguments),shouldCreateMcpTask(request.params,requestContext))return createMcpTaskForToolCall(request.params,requestContext);try{return buildMcpCompleteResult(await handleToolCall(request.params,clientInfo,hasMcpClientExtension(requestContext,PM_MCP_PROGRESSIVE_DISCOVERY_EXTENSION)),PM_MCP_SERVER_INFO)}catch(error){if(!(error instanceof PmMcpInputRequiredError))throw error;return buildMcpInputRequiredResult({requestContext,serverInfo:PM_MCP_SERVER_INFO,inputRequests:error.inputRequests,requestState:error.requestState})}}async function dispatchModernResourceMethod(request,requestContext){if(request.method==="resources/list"){const resources=[...PM_MCP_RESOURCE_CONTRACTS,...hasCompatiblePmMcpAppsCapability(requestContext)?PM_MCP_APP_CONTRACTS.map(contract=>({uri:contract.uri,name:contract.name,description:contract.description,mimeType:PM_MCP_APP_MIME_TYPE,_meta:{ui:contract.resourceMeta}})):[]].sort((left,right)=>left.uri.localeCompare(right.uri));return buildMcpCompleteResult(withMcpCachePolicy({resources},PM_MCP_CACHE_POLICIES.resources),PM_MCP_SERVER_INFO)}if(request.method==="resources/templates/list")return buildMcpCompleteResult(withMcpCachePolicy({resourceTemplates:[]},PM_MCP_CACHE_POLICIES.resources),PM_MCP_SERVER_INFO);try{const uri=readRequiredString(asRecordClone(request.params),"uri"),app=findPmMcpAppByUri(uri);let resource;if(app){if(!hasPmMcpAppsCapability(requestContext))throw new PmMcpProtocolError("MCP App resource requires negotiated client capability",PM_MCP_ERROR_CODES.missingRequiredClientCapability,{requiredCapabilities:{extensions:{[PM_MCP_APPS_EXTENSION]:PM_MCP_APPS_SERVER_CAPABILITY}}});resource={contents:[{uri,mimeType:PM_MCP_APP_MIME_TYPE,text:renderPmMcpAppHtml(app),_meta:{ui:app.resourceMeta}}]}}else uri.startsWith("skill://")?(assertPmMcpSkillsCapability(requestContext),resource={...(await loadRequestSkillRegistry(request.params)).read(uri)}):resource=await readWorkspaceResource(uri,request.params);return buildMcpCompleteResult(withMcpCachePolicy(resource,PM_MCP_CACHE_POLICIES.resource),PM_MCP_SERVER_INFO)}catch(error){throw!(error instanceof PmCliError)||!error.message.startsWith("Unknown pm MCP resource:")?error:new PmMcpProtocolError(error.message,PM_MCP_ERROR_CODES.invalidParams,{field:"uri"})}}function hasCompatiblePmMcpAppsCapability(requestContext){try{return hasPmMcpAppsCapability(requestContext)}catch(error){if(error instanceof PmMcpProtocolError)return!1;throw error}}function readSkillPageOptions(params){if(params.cursor!==void 0&&typeof params.cursor!="string")throw new PmMcpProtocolError("Skills cursor must be a string",PM_MCP_ERROR_CODES.invalidParams,{field:"cursor"});if(params.limit!==void 0&&typeof params.limit!="number")throw new PmMcpProtocolError("Skills limit must be a number",PM_MCP_ERROR_CODES.invalidParams,{field:"limit"});return{...typeof params.cursor=="string"?{cursor:params.cursor}:{},...typeof params.limit=="number"?{limit:params.limit}:{}}}async function dispatchModernSkillMethod(request,requestContext){const directoryRead=request.method==="resources/directory/read";assertPmMcpSkillsCapability(requestContext,directoryRead);const params=asRecordClone(request.params),registry=await loadRequestSkillRegistry(request.params);let result;return request.method==="skills/list"?result={...registry.list(readSkillPageOptions(params))}:request.method==="skills/get"?result={skill:registry.get(readRequiredString(params,"uri"))}:result={...registry.readDirectory(readRequiredString(params,"uri"),readSkillPageOptions(params))},buildMcpCompleteResult(withMcpCachePolicy(result,PM_MCP_CACHE_POLICIES.resource),PM_MCP_SERVER_INFO)}function dispatchModernPromptMethod(request){const result=request.method==="prompts/list"?withMcpCachePolicy({prompts:PM_MCP_PROMPT_CONTRACTS.map(prompt=>({name:prompt.name,description:prompt.description,arguments:prompt.arguments})).sort((left,right)=>left.name.localeCompare(right.name))},PM_MCP_CACHE_POLICIES.prompts):renderWorkflowPrompt(request.params);return buildMcpCompleteResult(result,PM_MCP_SERVER_INFO)}async function dispatchModernMcpRequest(request,meta){const requestContext=resolveMcpRequestContext(request.params),clientInfo=readMcpClientInfo(meta[PM_MCP_META_KEYS.clientInfo]);if(request.method==="server/discover")return buildMcpDiscoverResult({serverInfo:PM_MCP_SERVER_INFO,capabilities:PM_MCP_SERVER_CAPABILITIES,instructions:PM_MCP_INSTRUCTIONS});if(request.method==="ping")throw new PmMcpProtocolError("MCP method not found: ping",-32601,{removedIn:PM_MCP_PROTOCOL_VERSION});if(PM_MCP_SKILL_METHODS.has(request.method??""))return dispatchModernSkillMethod(request,requestContext);if(request.method==="tasks/get"||request.method==="tasks/update"||request.method==="tasks/cancel")return dispatchMcpTaskMethod(request,requestContext);if(request.method==="tools/list"||request.method==="tools/call")return dispatchModernToolMethod(request,requestContext,clientInfo);if(request.method==="resources/list"||request.method==="resources/templates/list"||request.method==="resources/read")return dispatchModernResourceMethod(request,requestContext);if(request.method==="prompts/list"||request.method==="prompts/get")return dispatchModernPromptMethod(request);throw new PmMcpProtocolError(`MCP method not found: ${request.method??"(missing)"}`,-32601)}async function handleRequestInReproducibleContext(request){if(!(!request.id&&request.method?.startsWith("notifications/"))){if(hasMcpProtocolVersionMetadata(request)){const allowlist=(process.env.PM_MCP_BAGGAGE_ALLOWLIST??"").split(",").map(entry=>entry.trim()).filter(Boolean);return runWithMcpTraceContext(extractMcpTraceContext(request.params,{baggageAllowlist:allowlist}),()=>dispatchModernMcpRequest(request,request.params._meta))}return request.method==="initialize"?LEGACY_MCP_ADAPTER.initialize(request.params):LEGACY_MCP_ADAPTER.dispatch(request)}}function hasMcpProtocolVersionMetadata(request){const meta=isMcpRecord(request.params)?request.params._meta:void 0;return isMcpRecord(meta)&&Object.prototype.hasOwnProperty.call(meta,PM_MCP_META_KEYS.protocolVersion)}async function handleRequest(request){return runWithReproducibleProcessEnvironment(process.env,()=>handleRequestInReproducibleContext(request))}function writeResponse(id,payload){process.stdout.write(`${JSON.stringify({jsonrpc:"2.0",id,result:payload})}
|
|
3
3
|
`)}function writeError(id,error){const code=error instanceof PmMcpProtocolError?error.code:error instanceof PmCliError?error.exitCode:-32603,message=error instanceof Error?error.message:String(error),data=error instanceof PmMcpProtocolError?error.data:error instanceof PmCliError?error.context:void 0;process.stdout.write(`${JSON.stringify({jsonrpc:"2.0",id,error:{code,message,data}})}
|
|
4
4
|
`)}function writeToolCallErrorResponse(request,error){return request.method!=="tools/call"||error instanceof PmMcpProtocolError?!1:(writeResponse(request.id,buildMcpToolCallErrorResult(request,error)),!0)}async function handleStdioTransportControl(request){if(request.method==="subscriptions/listen")return await openMcpSubscription({request,sink:notification=>{process.stdout.write(`${JSON.stringify(notification)}
|
|
5
5
|
`)}}),!0;if(request.method!=="notifications/cancelled")return!1;const requestId=request.params?.requestId;if(typeof requestId=="string"||typeof requestId=="number"){const result=closeMcpSubscription(requestId);result&&writeResponse(requestId,result)}return!0}async function processRpcLineWithHandler(line,requestHandler){if(line.trim().length===0)return;let request;try{request=JSON.parse(line)}catch(error){const message=error instanceof Error?error.message:String(error);writeError(null,new PmCliError(`Parse error: ${message}`,-32700));return}if(typeof request!="object"||request===null||Array.isArray(request)){writeError(null,new PmCliError("Invalid JSON-RPC request: expected an object",-32600));return}const shouldRespond=Object.prototype.hasOwnProperty.call(request,"id");try{if(await handleStdioTransportControl(request))return;const result=await requestHandler(request);shouldRespond&&result!==void 0&&writeResponse(request.id,result)}catch(error){if(!shouldRespond)return;writeToolCallErrorResponse(request,error)||writeError(request.id,error)}}async function processRpcLine(line){await processRpcLineWithHandler(line,handleRequest)}function startMcpServer(){const rl=readline.createInterface({input:process.stdin,crlfDelay:1/0}),queue=createSerialQueue();let processLine;try{const runInProcessContext=createReproducibleProcessRunner(process.env);processLine=line=>runInProcessContext(()=>processRpcLineWithHandler(line,handleRequestInReproducibleContext))}catch{processLine=processRpcLine}rl.on("line",line=>{queue.enqueue(()=>processLine(line))}),rl.on("close",()=>{queue.enqueue(()=>{for(const closed of closeStdioMcpSubscriptions())writeResponse(closed.id,closed.result)})})}function isInvokedAsMcpMainModule(argvPath,moduleUrl){if(!argvPath)return!1;const selfPath=fileURLToPath(moduleUrl);if(argvPath===selfPath)return!0;try{return realpathSync(argvPath)===realpathSync(selfPath)}catch{return!1}}function readRuntimeTestHook(key){const runtimeTestHooks=globalThis.__pmCliActionRunnerTestHooks;if(runtimeTestHooks===void 0)throw new PmCliError(`MCP runtime test hook "${String(key)}" is only available in test environments.`,64);return runtimeTestHooks[key]}const _testOnly={boundMcpClientProvenance,createMcpInputRequiredError:input=>new PmMcpInputRequiredError(input),createMcpProtocolError:(...input)=>new PmMcpProtocolError(...input),get closeManyOptionsFromFlat(){return readRuntimeTestHook("closeManyOptionsFromFlat")},detectUnexpectedOptionKeys,detectUnexpectedTopLevelKeys,collectMutationGuardWarnings,closeStdioMcpSubscriptions,errorContent,emitMcpChangeNotifications,expireMcpSubscriptionRecord:(id,key=id)=>PM_MCP_SUBSCRIPTIONS.get(key).registry.close(id),getMcpClientInfo:()=>LEGACY_MCP_ADAPTER.getClientInfo(),get extensionOptionsFromArgs(){return readRuntimeTestHook("extensionOptionsFromArgs")},get globalOptions(){return readRuntimeTestHook("globalOptions")},get mutationListOptions(){return readRuntimeTestHook("mutationListOptions")},nearestDeclaredKey,mcpTaskPrincipal,resultContent,resolveMcpRequestContext,shouldCreateMcpTask,settleMcpTaskExecution,subscriptionCount:()=>PM_MCP_SUBSCRIPTIONS.size,get normalizeActionName(){return readRuntimeTestHook("normalizeActionName")},get normalizeCommandPath(){return readRuntimeTestHook("normalizeCommandPath")},get normalizeMcpOptionsArrays(){return readRuntimeTestHook("normalizeMcpOptionsArrays")},get normalizeMcpUpdateOptions(){return readRuntimeTestHook("normalizeMcpUpdateOptions")},get optionsWithAuthor(){return readRuntimeTestHook("optionsWithAuthor")},get readRequiredString(){return readRuntimeTestHook("readRequiredString")},get readScalarString(){return readRuntimeTestHook("readScalarString")},get readScalarStringAllowBlank(){return readRuntimeTestHook("readScalarStringAllowBlank")},get readStringArray(){return readRuntimeTestHook("readStringArray")},runAction:runMcpAction,get updateManyOptionsFromFlat(){return readRuntimeTestHook("updateManyOptionsFromFlat")},get withAddNoteOption(){return readRuntimeTestHook("withAddNoteOption")},get withFilesDiscoveryOptions(){return readRuntimeTestHook("withFilesDiscoveryOptions")},get withMutationCompaction(){return readRuntimeTestHook("withMutationCompaction")},writeError};isInvokedAsMcpMainModule(process.argv[1],import.meta.url)&&startMcpServer();export{_testOnly,buildMcpToolCallErrorResult,closeMcpSubscription,handleRequest,isInvokedAsMcpMainModule,openMcpSubscription,processRpcLine,resolveMcpToolSchemaForRequest,startMcpServer};
|
package/dist/sdk/core.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export { BASELINE_ITEM_FORMAT_VERSION,BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CURRENT_ITEM_FORMAT_VERSION,DEPENDENCY_KIND_VALUES,EXIT_CODE,ISSUE_SEVERITY_VALUES,ITEM_TYPE_VALUES,PM_CLI_EXPECTED_ERROR_NAME,PmCliError,PmClient,RISK_VALUES,STATUS_VALUES,canonicalDocument,classifyItemFormatVersion,createPmCliExpectedError,effectiveItemFormatVersion,emptyImportedDocument,isPmCliExpectedError,normalizeItemFormatVersion,normalizeItemId,normalizeStatusInput,nowIso,runAction,serializeItemDocument,aggregate,append,claim,claimNext,close,comments,context,copy,create,deleteItem,deps,docs,files,filesDiscover,focus,get,graph,learnings,list,next,notes,release,reopen,restore,search,update,type AggregateOptions,type AggregateResult,type AggregateRow,type AssuranceActionInput,type AssuranceActionResult,type AppendCommandOptions,type AppendResult,type ClaimNextOptions,type ClaimResult,type CloseResult,type CommentsCommandOptions,type CommentsResult,type ContextOptions,type ContextResult,type CopyResult,type CreateResult,type Dependency,type DeleteResult,type DepsCommandOptions,type DepsResult,type DocsCommandOptions,type DocsResult,type FilesCommandOptions,type FilesDiscoverOptions,type FilesDiscoverResult,type FilesResult,type FocusResult,type GetOptions,type GetResult,type ItemFormatVersionScanEntry,type ItemFormatVersionScanResult,type ItemFormatVersionStatus,type LearningsCommandOptions,type LearningsResult,type ListOptions,type ListResult,listAllComplete,type PmCompleteListOptions,type PmCompleteListResult,type NextOptions,type NextResult,type NotesCommandOptions,type NotesResult,type PmActionInput,type PmActionName,type PmActionOptions,type PmClientOptions,type ReleaseResult,type ReleaseMutationOptions,type PreviousTerminalEvidence,type RecurrenceReceipt,type ReopenCommandOptions,type ReopenResult,type RestoreResult,type SearchOptions,type SearchResult,type UpdateResult,} from "./runtime.js";
|
|
7
7
|
export * from "./core-governance.js";
|
|
8
8
|
export { updateLinkedTest,type LinkedTestUpdateSelector,type LinkedTestMetadataPatch,type UpdateLinkedTestOptions,type UpdateLinkedTestResult,} from "./test/update.js";
|
|
9
|
-
export { isItemAlreadyExistsError,type PmItemAlreadyExistsError } from "./errors.js";
|
|
9
|
+
export { isItemAlreadyExistsError,type PmItemAlreadyExistsError,isPmTokenBudgetRecovery,type PmTokenBudgetRecovery } from "./errors.js";
|
|
10
10
|
export * from "./agent-session-context.js";
|
|
11
11
|
export { isAlreadyClaimedError } from "./lifecycle/claim.js";
|
|
12
12
|
export { PM_READ_OUTPUT_DIMENSIONS,PM_READ_OUTPUT_OPTION_FLAGS,PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS,PM_READ_OUTPUT_SURFACE_CONTRACTS,applyReadOutputDimensions,decodeReadOutputContinuationCursor,encodeReadOutputContinuationCursor,isReadOutputBudgetExceeded,resolveReadOutputDimensions,resolveReadOutputEncoding,resolveReadOutputSurface,validateReadOutputOptions,} from "./read-output-contracts.js";
|
package/dist/sdk/core.js
CHANGED
|
@@ -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]="c311d37b-532b-5eed-b7c1-82ddc829ddaf")}catch{}})();import{BASELINE_ITEM_FORMAT_VERSION,BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CURRENT_ITEM_FORMAT_VERSION,DEPENDENCY_KIND_VALUES,EXIT_CODE,ISSUE_SEVERITY_VALUES,ITEM_TYPE_VALUES,PM_CLI_EXPECTED_ERROR_NAME,PmCliError,PmClient,RISK_VALUES,STATUS_VALUES,canonicalDocument,classifyItemFormatVersion,createPmCliExpectedError,effectiveItemFormatVersion,emptyImportedDocument,isPmCliExpectedError,normalizeItemFormatVersion,normalizeItemId,normalizeStatusInput,nowIso,runAction,serializeItemDocument,aggregate,append,claim,claimNext,close,comments,context,copy,create,deleteItem,deps,docs,files,filesDiscover,focus,get,graph,learnings,list,next,notes,release,reopen,restore,search,update,listAllComplete}from"./runtime.js";export*from"./core-governance.js";import{updateLinkedTest}from"./test/update.js";import{isItemAlreadyExistsError,isPmTokenBudgetRecovery}from"./errors.js";export*from"./agent-session-context.js";import{isAlreadyClaimedError}from"./lifecycle/claim.js";import{PM_READ_OUTPUT_DIMENSIONS,PM_READ_OUTPUT_OPTION_FLAGS,PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS,PM_READ_OUTPUT_SURFACE_CONTRACTS,applyReadOutputDimensions,decodeReadOutputContinuationCursor,encodeReadOutputContinuationCursor,isReadOutputBudgetExceeded,resolveReadOutputDimensions,resolveReadOutputEncoding,resolveReadOutputSurface,validateReadOutputOptions}from"./read-output-contracts.js";import{applyReadOutputSessionReferences,attachReadOutputSessionReceipt,parseReadOutputSession,readOutputSessionRemainingTokens}from"./read-output-session.js";export{BASELINE_ITEM_FORMAT_VERSION,BUILTIN_ITEM_TYPE_VALUES,CONFIDENCE_TEXT_VALUES,CURRENT_ITEM_FORMAT_VERSION,DEPENDENCY_KIND_VALUES,EXIT_CODE,ISSUE_SEVERITY_VALUES,ITEM_TYPE_VALUES,PM_CLI_EXPECTED_ERROR_NAME,PM_READ_OUTPUT_COMPOSITION_OPTION_FLAGS,PM_READ_OUTPUT_DIMENSIONS,PM_READ_OUTPUT_OPTION_FLAGS,PM_READ_OUTPUT_SURFACE_CONTRACTS,PmCliError,PmClient,RISK_VALUES,STATUS_VALUES,aggregate,append,applyReadOutputDimensions,applyReadOutputSessionReferences,attachReadOutputSessionReceipt,canonicalDocument,claim,claimNext,classifyItemFormatVersion,close,comments,context,copy,create,createPmCliExpectedError,decodeReadOutputContinuationCursor,deleteItem,deps,docs,effectiveItemFormatVersion,emptyImportedDocument,encodeReadOutputContinuationCursor,files,filesDiscover,focus,get,graph,isAlreadyClaimedError,isItemAlreadyExistsError,isPmCliExpectedError,isPmTokenBudgetRecovery,isReadOutputBudgetExceeded,learnings,list,listAllComplete,next,normalizeItemFormatVersion,normalizeItemId,normalizeStatusInput,notes,nowIso,parseReadOutputSession,readOutputSessionRemainingTokens,release,reopen,resolveReadOutputDimensions,resolveReadOutputEncoding,resolveReadOutputSurface,restore,runAction,search,serializeItemDocument,update,updateLinkedTest,validateReadOutputOptions};
|
|
2
2
|
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/dependencies/context-budget-recovery
|
|
3
|
+
* Finds verified retry budgets while bounding query work and distinguishing proved minima from partial searches.
|
|
4
|
+
*/
|
|
5
|
+
import type { PmTokenBudgetRecovery } from "../../core/shared/errors.js";
|
|
6
|
+
/** A real packer probe distinguishes its own floor from an independent output constraint. */
|
|
7
|
+
export type ContextBudgetProbe = "fits" | "native_floor" | "output_constraints";
|
|
8
|
+
/** Inputs derived from one immutable relationship assembly and preserved retry options. */
|
|
9
|
+
interface ContextBudgetRecoveryInput {
|
|
10
|
+
/** Failed query's requested token ceiling. */
|
|
11
|
+
requested:number;
|
|
12
|
+
/** Initial upper candidate derived from the kernel's canonical default. */
|
|
13
|
+
initialBudget:number;
|
|
14
|
+
/** Conservative graph and text-size work estimate for each packer evaluation. */
|
|
15
|
+
workUnits:number;
|
|
16
|
+
/** Evaluate the real preserved query at one positive integer budget. */
|
|
17
|
+
probe:(tokens:number) => ContextBudgetProbe;
|
|
18
|
+
}
|
|
19
|
+
/** Establish a working retry and prove a global minimum only after exhaustive lower-budget verification. */
|
|
20
|
+
export declare function findContextBudgetRecovery(input:ContextBudgetRecoveryInput):PmTokenBudgetRecovery;
|
|
21
|
+
export {};
|
|
@@ -0,0 +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]="8a0c0e0d-7d3b-55c6-984b-b6570362cf78")}catch{}})();function unavailable(requested,reason){return{requested_tokens:requested,feasible_tokens:null,minimum_feasible_tokens:null,minimum_status:"unavailable",basis:"canonical_retry",reason}}function nativeUpperBound(input,probe){let upper=Math.min(Number.MAX_SAFE_INTEGER,Math.max(input.initialBudget,input.requested+1));for(let attempt=0;attempt<16;attempt+=1){if(probe(upper)!=="native_floor")return upper;if(upper===Number.MAX_SAFE_INTEGER)return;upper=Math.min(Number.MAX_SAFE_INTEGER,upper*2)}}function findContextBudgetRecovery(input){if(input.workUnits>1e6)return unavailable(input.requested,"query_cost_limit");const cache=new Map;let feasible;const probe=tokens=>{let outcome=cache.get(tokens);return outcome===void 0&&(outcome=input.probe(tokens),cache.set(tokens,outcome)),outcome==="fits"&&(feasible=Math.min(feasible??tokens,tokens)),outcome},upper=nativeUpperBound(input,probe);if(upper===void 0)return unavailable(input.requested,"search_limit");let left=0,right=upper;for(let step=0;step<24&&right-left>1;step+=1){const middle=left+Math.floor((right-left)/2);probe(middle)==="native_floor"?left=middle:right=middle}const verificationLimit=Math.min(feasible??upper,4096,Math.floor(1e5/Math.max(1,input.workUnits)));for(let tokens=1;tokens<=verificationLimit;tokens+=1)if(probe(tokens)==="fits")return{requested_tokens:input.requested,feasible_tokens:tokens,minimum_feasible_tokens:tokens,minimum_status:"exact",basis:"canonical_retry"};return feasible===void 0?unavailable(input.requested,"output_constraints"):{requested_tokens:input.requested,feasible_tokens:feasible,minimum_feasible_tokens:null,minimum_status:"feasible_only",basis:"canonical_retry"}}export{findContextBudgetRecovery};
|
|
2
|
+
//# sourceMappingURL=context-budget-recovery.js.map
|
package/dist/sdk/dependencies.js
CHANGED
|
@@ -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]="620bf4e4-e6d1-5520-89e4-0859f57c7afe")}catch{}})();import{assertInitializedTracker}from"./environment/tracker-preflight.js";import{getActiveExtensionRegistrations}from"../core/extensions/index.js";import{resolveItemTypeRegistry}from"../core/item/type-registry.js";import{isTerminalStatus}from"../core/item/status.js";import{resolveRuntimeStatusRegistry}from"../core/schema/runtime-schema.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{formatBuiltInOutput}from"../core/output/output.js";import{listAllItemMetadataLight,locateItem,readLocatedItem}from"../core/store/item-store.js";import{resolvePmRoot}from"../core/store/paths.js";import{readSettings}from"../core/store/settings.js";import{estimatePmOutputTokens}from"./cli-contracts/agent-output-contracts.js";import{assertProjectionModeChoice,attachOutputOmissionReceipt}from"./output-projection.js";import{assembleWorkspaceRelationshipGraph,collectDanglingDependencyReferences,resolveWorkspaceRelationshipKindRegistry}from"./graph/assembly.js";import{computeWorkspaceGraphFingerprint,workspaceGraphCache}from"./graph/cache.js";import{buildRelationshipContext}from"./relationship-context.js";import{createRelationshipKindRegistry}from"./relationships.js";const DEPS_FORMAT_VALUES=["tree","graph","context"],DEPS_COLLAPSE_VALUES=["none","repeated"],DEPS_DIRECTION_VALUES=["outgoing","incoming","both"],DEFAULT_DEPS_TREE_MAX_DEPTH=32,DEFAULT_DEPS_TREE_NODE_LIMIT=200,DEFAULT_DEPS_TREE_EDGE_LIMIT=400,DEFAULT_DEPS_TREE_TOKEN_BUDGET=16e3;function parseFormat(raw){const candidate=raw?.trim().toLowerCase()??"tree";if(DEPS_FORMAT_VALUES.includes(candidate))return candidate;throw new PmCliError(`Invalid --format value "${raw}". Use "tree", "graph", or "context".`,EXIT_CODE.USAGE)}function parsePositiveInteger(raw,flag){if(raw===void 0)return;const value=typeof raw=="number"?raw:Number(raw.trim());if(!Number.isInteger(value)||value<1)throw new PmCliError(`Invalid --${flag} value "${raw}". Use a positive integer.`,EXIT_CODE.USAGE);return value}function parseMaxDepth(raw){if(raw===void 0)return;const normalized=typeof raw=="number"?raw:Number(raw.trim());if(!Number.isInteger(normalized)||normalized<0)throw new PmCliError(`Invalid --max-depth value "${raw}". Use a non-negative integer.`,EXIT_CODE.USAGE);return normalized}function parseCollapse(raw){const candidate=raw?.trim().toLowerCase()??"none";if(DEPS_COLLAPSE_VALUES.includes(candidate))return candidate;throw new PmCliError(`Invalid --collapse value "${raw}". Use "none" or "repeated".`,EXIT_CODE.USAGE)}function parseDirection(raw){const candidate=raw?.trim().toLowerCase()??"both";if(DEPS_DIRECTION_VALUES.includes(candidate))return candidate;throw new PmCliError(`Invalid --direction value "${raw}". Use "outgoing", "incoming", or "both".`,EXIT_CODE.USAGE)}function parseKinds(raw,registry=createRelationshipKindRegistry()){if(raw===void 0)return;const values=(Array.isArray(raw)?raw:[raw]).flatMap(value=>value.split(",")).map(value=>value.trim()).filter(value=>value.length>0);if(values.length===0)return;const kinds=new Set;for(const value of values){const definition=registry.resolve(value);if(!definition){const known=registry.list().map(entry=>entry.kind).join(", ");throw new PmCliError(`Invalid --kind value "${value}". Registered kinds: ${known}.`,EXIT_CODE.USAGE)}kinds.add(definition.kind)}return[...kinds].sort()}function normalizeDependencies(dependencies){if(!dependencies||dependencies.length===0)return[];const sorted=dependencies.map(({id,kind})=>({id:id.trim(),kind:kind.trim().toLowerCase()})).sort((left,right)=>{const byKind=left.kind.localeCompare(right.kind);return byKind!==0?byKind:left.id.localeCompare(right.id)}),deduped=new Map;for(const dependency of sorted){const key=`${dependency.kind.toLowerCase()}::${dependency.id.toLowerCase()}`;deduped.has(key)||deduped.set(key,{id:dependency.id,kind:dependency.kind})}return[...deduped.values()]}function toIndexedItem(item){return{id:item.id,title:item.title,type:item.type,status:item.status,dependencies:normalizeDependencies(item.dependencies)}}function estimateTreeNodeTokens(node){return estimatePmOutputTokens(new TextEncoder().encode(JSON.stringify({...node,dependencies:void 0})).byteLength)}function appendTreeDependencies(baseNode,item,index,nextLineage,maxDepth,collapse,expanded,budget,depth){for(const dependency of item.dependencies){const edgeTokens=Math.max(1,Math.ceil(JSON.stringify({from:baseNode.id,to:dependency.id,kind:dependency.kind}).length/3));if(budget.nodes>=budget.nodeLimit){baseNode.truncated=!0,budget.reasons.add("node_limit");break}if(budget.edges>=budget.edgeLimit){baseNode.truncated=!0,budget.reasons.add("edge_limit");break}if(budget.estimatedTokens+edgeTokens>=budget.tokenBudget){baseNode.truncated=!0,budget.reasons.add("token_budget");break}budget.edges+=1,budget.estimatedTokens+=edgeTokens,baseNode.dependencies.push(toTreeNode(dependency.id,index,nextLineage,maxDepth,collapse,expanded,budget,depth+1,dependency.kind))}}function shouldStopTreeNodeExpansion(node,item,lookupId,maxDepth,collapse,expanded,budget,depth){return budget.estimatedTokens>=budget.tokenBudget&&item?.dependencies.length?(node.truncated=!0,budget.reasons.add("token_budget"),!0):!item||node.cycle?!0:maxDepth!==void 0&&depth>=maxDepth?(item.dependencies.length>0&&(node.truncated=!0,budget.reasons.add("max_depth")),!0):collapse==="repeated"&&expanded.has(lookupId)?(node.collapsed=!0,!0):!1}function toTreeNode(id,index,lineage,maxDepth,collapse,expanded,budget,depth=0,via){const lookupId=id.trim().toLowerCase(),item=index.get(lookupId),baseNode={id:item?.id??id,title:item?.title,type:item?.type,status:item?.status,via,missing:!item,cycle:lineage.has(lookupId),dependencies:[]};if(budget.nodes+=1,budget.estimatedTokens+=estimateTreeNodeTokens(baseNode),shouldStopTreeNodeExpansion(baseNode,item,lookupId,maxDepth,collapse,expanded,budget,depth))return baseNode;collapse==="repeated"&&expanded.add(lookupId);const nextLineage=new Set(lineage);return nextLineage.add(lookupId),appendTreeDependencies(baseNode,item,index,nextLineage,maxDepth,collapse,expanded,budget,depth),baseNode}function mergeGraphNode(existing,candidate){return!existing||existing.missing&&!candidate.missing?candidate:{...existing,title:existing.title??candidate.title,type:existing.type??candidate.type,status:existing.status??candidate.status}}function toGraph(root){const nodesById=new Map,edgesByKey=new Map,pending=[root];for(;pending.length>0;){const node=pending.pop();nodesById.set(node.id,mergeGraphNode(nodesById.get(node.id),{id:node.id,title:node.title,type:node.type,status:node.status,missing:node.missing}));for(const child of node.dependencies){nodesById.set(child.id,mergeGraphNode(nodesById.get(child.id),{id:child.id,title:child.title,type:child.type,status:child.status,missing:child.missing}));const relationKind=child.via??"related",edgeKey=`${node.id}::${child.id}::${relationKind}`;edgesByKey.has(edgeKey)||edgesByKey.set(edgeKey,{from:node.id,to:child.id,kind:relationKind}),child.cycle||pending.push(child)}}const nodes=[...nodesById.values()].sort((left,right)=>left.id.localeCompare(right.id)),edges=[...edgesByKey.values()].sort((left,right)=>{const byFrom=left.from.localeCompare(right.from);if(byFrom!==0)return byFrom;const byTo=left.to.localeCompare(right.to);return byTo!==0?byTo:left.kind.localeCompare(right.kind)}),missingIds=nodes.filter(node=>node.missing).map(node=>node.id);return{root_id:root.id,nodes,edges,missing_ids:missingIds}}function countDependencyGraph(rootId,index,maxDepth){const nodeIds=new Set,edgeKeys=new Set,missingIds=new Set,expanded=new Set,pending=[{id:rootId,depth:0}];let pendingIndex=0;for(;pendingIndex<pending.length;){const current=pending[pendingIndex++],lookupId=current.id.trim().toLowerCase();nodeIds.add(lookupId);const item=index.get(lookupId);if(!item){missingIds.add(lookupId);continue}if(!(maxDepth!==void 0&¤t.depth>=maxDepth)&&!expanded.has(lookupId)){expanded.add(lookupId);for(const dependency of item.dependencies)edgeKeys.add(`${lookupId}::${dependency.id.trim().toLowerCase()}::${dependency.kind}`),pending.push({id:dependency.id,depth:current.depth+1})}}return{node_count:nodeIds.size,edge_count:edgeKeys.size,edge_basis:"deduplicated_directed",missing_count:missingIds.size}}function parseDepsContextOptions(options,registry=createRelationshipKindRegistry()){const maxDepth=parseMaxDepth(options.maxDepth),nodeLimit=parsePositiveInteger(options.nodeLimit,"node-limit"),edgeLimit=parsePositiveInteger(options.edgeLimit,"edge-limit"),tokenBudget=parsePositiveInteger(options.tokenBudget,"token-budget"),kinds=parseKinds(options.kind,registry);return{direction:parseDirection(options.direction),...kinds===void 0?{}:{kinds},...maxDepth===void 0?{}:{maxDepth},...nodeLimit===void 0?{}:{nodeLimit},...edgeLimit===void 0?{}:{edgeLimit},...tokenBudget===void 0?{}:{tokenBudget},...options.cursor?.trim()?{cursor:options.cursor.trim()}:{}}}function buildContextFromAssembly(assembly,rootId,options,rootEvidence){return buildRelationshipContext(assembly.graph,rootId,assembly.details.map(detail=>detail.id===rootId&&rootEvidence.length>0?{...detail,evidence:rootEvidence}:detail),options)}function buildDepsRelationshipContext(rootId,items,options,rootEvidence=[]){const assembly=assembleWorkspaceRelationshipGraph(items);return buildContextFromAssembly(assembly,rootId,parseDepsContextOptions(options,assembly.graph.registry()),rootEvidence)}function appendEvidencePointers(evidence,label,values,limit){for(const value of values.slice(0,limit)){const trimmed=value?.trim();trimmed&&evidence.push(`${label}:${trimmed}`)}}async function collectRootEvidence(pmRoot,id,settings,typeToFolder){const located=await locateItem(pmRoot,id,settings.id_prefix,settings.item_format,typeToFolder);if(!located)return[];const{document}=await readLocatedItem(located,{schema:settings.schema}),metadata=document.metadata,files=metadata.files??[],tests=metadata.tests??[],docs=metadata.docs??[],counts=[["files",files.length],["tests",tests.length],["docs",docs.length],["comments",(metadata.comments??[]).length],["notes",(metadata.notes??[]).length],["learnings",(metadata.learnings??[]).length]];if(counts.every(([,count])=>count===0))return[];const evidence=[`linked:${counts.map(([key,count])=>`${key}=${count}`).join(",")}`];return appendEvidencePointers(evidence,"file",files.map(file=>file.path),3),appendEvidencePointers(evidence,"test",tests.map(test=>test.command??test.path),2),appendEvidencePointers(evidence,"doc",docs.map(doc=>doc.path),2),evidence}function createContextDepsResult(params){const{canonicalId,context,missingCount,missingReferences,referenceLimit,summaryOnly}=params;return{id:canonicalId,format:"context",node_count:context.nodes.length+1,edge_count:context.edges.length,edge_basis:"deduplicated_directed",missing_count:missingCount,missing_scope:"traversal",missing_reference_count:missingReferences.length,...summaryOnly?{}:{missing_references:missingReferences.slice(0,referenceLimit),context}}}function includesContextMissingReference(params){const{row,missingReachableSet,packetIds,filteredKinds,registry}=params;if(row.no_active_blocker_sentinel||!missingReachableSet.has(row.target_id.trim().toLowerCase())||!packetIds.has(row.holder_id))return!1;if(filteredKinds===void 0)return!0;const definition=registry.resolve(row.kind);return definition!==void 0&&(filteredKinds.has(definition.kind)||definition.inverse!==void 0&&filteredKinds.has(definition.inverse))}function settleRenderedTokenCount(result,outputFormat,assign){let embeddedTokens;for(;;){const measuredTokens=estimatePmOutputTokens(new TextEncoder().encode(formatBuiltInOutput(attachOutputOmissionReceipt("deps",result),outputFormat)).byteLength);if(measuredTokens===embeddedTokens)return measuredTokens;assign(measuredTokens),embeddedTokens=measuredTokens}}function isContextBudgetFloorError(error){return error instanceof TypeError&&error.message.startsWith("Relationship context tokenBudget cannot fit ")}function buildContextAtRenderedBudget(params){try{return buildContextFromAssembly(params.assembly,params.canonicalId,{...params.contextOptions,...params.internalTokenBudget===void 0?{}:{tokenBudget:params.internalTokenBudget}},params.rootEvidence)}catch(error){if(params.smallestResult!==void 0&&isContextBudgetFloorError(error))return params.smallestResult;throw error}}function enforceContextRenderedTokenBudget(params){const{assembly,canonicalId,contextOptions,rootEvidence,summaryOnly,outputFormat,missingCount,missingReferences}=params;let emittedReferenceLimit=contextOptions.edgeLimit??40,internalTokenBudget=contextOptions.tokenBudget,requestedTokenBudget,smallestResult;for(;;){const contextOrFloor=buildContextAtRenderedBudget({assembly,canonicalId,contextOptions,internalTokenBudget,rootEvidence,smallestResult});if("format"in contextOrFloor)return contextOrFloor;const context=contextOrFloor;requestedTokenBudget??=context.meta.tokenBudget,internalTokenBudget??=requestedTokenBudget;const result=createContextDepsResult({canonicalId,context,missingCount,missingReferences,referenceLimit:emittedReferenceLimit,summaryOnly});if(smallestResult=result,summaryOnly||(context.meta.tokenBudget=requestedTokenBudget,context.meta.usedTokens=settleRenderedTokenCount(attachDepsProjection(result,!1),outputFormat,tokens=>{context.meta.usedTokens=tokens}),context.meta.usedTokens<=requestedTokenBudget))return result;if(emittedReferenceLimit>0){emittedReferenceLimit-=1;continue}const currentInternalBudget=internalTokenBudget,scaledInternalBudget=currentInternalBudget*requestedTokenBudget/context.meta.usedTokens;internalTokenBudget=Math.min(currentInternalBudget-1,Math.max(1,Math.floor(scaledInternalBudget*.9)))}}function buildContextDepsResult(params){const{assembly,canonicalId,options,rootEvidence,summaryOnly,outputFormat}=params,contextOptions=parseDepsContextOptions(options,assembly.graph.registry()),reachable=assembly.graph.closure(canonicalId,{direction:contextOptions.direction,...contextOptions.kinds===void 0?{}:{kinds:contextOptions.kinds},maxDepth:contextOptions.maxDepth??3}),missingReachable=reachable.value.filter(nodeId=>assembly.missingIdSet.has(nodeId.toLowerCase())),missingReachableSet=new Set(missingReachable.map(nodeId=>nodeId.toLowerCase())),relationshipRegistry=assembly.graph.registry(),filteredKinds=contextOptions.kinds?new Set(contextOptions.kinds.map(kind=>relationshipRegistry.require(kind).kind)):void 0,packetIds=new Set([canonicalId,...reachable.value]),missingReferences=[...assembly.dangling.active,...assembly.dangling.legacy_terminal].filter(row=>includesContextMissingReference({row,missingReachableSet,packetIds,filteredKinds,registry:relationshipRegistry}));return enforceContextRenderedTokenBudget({assembly,canonicalId,contextOptions,rootEvidence,summaryOnly,outputFormat,missingCount:missingReachable.length,missingReferences})}function trimDeepestDependency(tree){const pending=[tree];let parentToTrim;for(;pending.length>0;){const current=pending.pop();current.dependencies.length>0&&(parentToTrim=current,pending.push(...current.dependencies))}return parentToTrim?(parentToTrim.dependencies.pop(),parentToTrim.truncated=!0,!0):!1}function buildTreeOrGraphDepsResult(id,format,options,index,maxDepth,collapse,outputFormat){const effectiveMaxDepth=maxDepth??DEFAULT_DEPS_TREE_MAX_DEPTH,nodeLimit=parsePositiveInteger(options.nodeLimit,"node-limit")??DEFAULT_DEPS_TREE_NODE_LIMIT,edgeLimit=parsePositiveInteger(options.edgeLimit,"edge-limit")??DEFAULT_DEPS_TREE_EDGE_LIMIT,tokenBudget=parsePositiveInteger(options.tokenBudget,"token-budget")??DEFAULT_DEPS_TREE_TOKEN_BUDGET,budget={nodeLimit,edgeLimit,tokenBudget,nodes:0,edges:0,estimatedTokens:0,reasons:new Set},tree=toTreeNode(id,index,new Set,effectiveMaxDepth,format==="graph"?"repeated":collapse,new Set,budget),totals=countDependencyGraph(id,index,void 0);let result;for(;;){const graph=toGraph(tree),truncation=budget.reasons.size===0?void 0:{reasons:[...budget.reasons].sort(),limits:{max_depth:effectiveMaxDepth,node_limit:nodeLimit,edge_limit:edgeLimit,token_budget:tokenBudget},estimated_tokens:0,total_node_count:totals.node_count,total_edge_count:totals.edge_count,omitted_node_count:Math.max(0,totals.node_count-graph.nodes.length),omitted_edge_count:Math.max(0,totals.edge_count-graph.edges.length)},baseResult={id,format,node_count:graph.nodes.length,edge_count:graph.edges.length,edge_basis:"deduplicated_directed",missing_count:graph.missing_ids.length,...truncation?{truncation}:{}};if(result=format==="tree"?{...baseResult,tree}:{...baseResult,graph},(result.truncation===void 0?estimatePmOutputTokens(new TextEncoder().encode(formatBuiltInOutput(attachOutputOmissionReceipt("deps",attachDepsProjection(result,!1)),outputFormat)).byteLength):settleRenderedTokenCount(attachDepsProjection(result,!1),outputFormat,tokens=>{result.truncation.estimated_tokens=tokens}))<=tokenBudget)return result;if(!trimDeepestDependency(tree))return budget.reasons.add("token_budget"),result;budget.reasons.add("token_budget")}}function attachDepsProjection(result,summaryOnly,legacyAliasCounts={}){const group={name:result.format==="tree"?"dependency_tree":result.format==="graph"?"dependency_graph":"relationship_context",restore_with:"--full"};return{...result,legacy_alias_counts:legacyAliasCounts,projection:{mode:summaryOnly?"summary":"full",declared_field_groups:[group],included_field_groups:summaryOnly?[]:[group.name]}}}async function runDeps(id,options,global2){const pmRoot=resolvePmRoot(process.cwd(),global2.path);await assertInitializedTracker(pmRoot);const format=parseFormat(options.format),maxDepth=parseMaxDepth(options.maxDepth),collapse=parseCollapse(options.collapse);assertProjectionModeChoice(options.summary===!0,options.full===!0,"--summary");const summaryOnly=options.summary===!0,settings=await readSettings(pmRoot),typeRegistry=resolveItemTypeRegistry(settings,getActiveExtensionRegistrations()),items=await listAllItemMetadataLight(pmRoot,settings.item_format,typeRegistry.type_to_folder,void 0,settings.schema),statusRegistry=resolveRuntimeStatusRegistry(settings.schema),index=new Map(items.map(item=>[item.id.trim().toLowerCase(),toIndexedItem(item)])),dangling=collectDanglingDependencyReferences(items,status=>isTerminalStatus(status,statusRegistry));for(const reference of[...dangling.active,...dangling.legacy_terminal]){const holder=index.get(reference.holder_id.trim().toLowerCase()),referenceKind=reference.kind.trim().toLowerCase();holder&&!holder.dependencies.some(dependency=>dependency.id.trim().toLowerCase()===reference.target_id.trim().toLowerCase()&&dependency.kind===referenceKind)&&holder.dependencies.push({id:reference.target_id,kind:referenceKind})}if(!index.has(id.trim().toLowerCase()))throw new PmCliError(`Item ${id} not found`,EXIT_CODE.NOT_FOUND);if(format==="context"){const canonicalId=index.get(id.trim().toLowerCase()).id,rootEvidence=summaryOnly?[]:await collectRootEvidence(pmRoot,canonicalId,settings,typeRegistry.type_to_folder),isTerminal=status=>isTerminalStatus(status,statusRegistry),relationshipRegistry=resolveWorkspaceRelationshipKindRegistry(),lookup=workspaceGraphCache().lookup(pmRoot,computeWorkspaceGraphFingerprint(items,isTerminal,relationshipRegistry),()=>assembleWorkspaceRelationshipGraph(items,isTerminal,relationshipRegistry));return attachDepsProjection(buildContextDepsResult({assembly:lookup.assembly,canonicalId,options,rootEvidence,summaryOnly,outputFormat:global2.json===!0?"json":"toon"}),summaryOnly,lookup.assembly.legacyAliasCounts)}return summaryOnly?attachDepsProjection({id,format,...countDependencyGraph(id,index,maxDepth)},!0,Object.fromEntries(Object.entries(assembleWorkspaceRelationshipGraph(items,status=>isTerminalStatus(status,statusRegistry)).legacyAliasCounts))):attachDepsProjection(buildTreeOrGraphDepsResult(id,format,options,index,maxDepth,collapse,global2.json===!0?"json":"toon"),!1,Object.fromEntries(Object.entries(assembleWorkspaceRelationshipGraph(items,status=>isTerminalStatus(status,statusRegistry)).legacyAliasCounts)))}export{DEPS_COLLAPSE_VALUES,DEPS_DIRECTION_VALUES,DEPS_FORMAT_VALUES,buildDepsRelationshipContext,parseDirection,parseKinds,parseMaxDepth,parsePositiveInteger,runDeps};
|
|
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]="e574946e-ad2d-5465-a021-205300ab3596")}catch{}})();import{assertInitializedTracker}from"./environment/tracker-preflight.js";import{getActiveCommandContext,getActiveExtensionRegistrations}from"../core/extensions/index.js";import{resolveItemTypeRegistry}from"../core/item/type-registry.js";import{isTerminalStatus}from"../core/item/status.js";import{resolveRuntimeStatusRegistry}from"../core/schema/runtime-schema.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{formatBuiltInOutput}from"../core/output/output.js";import{listAllItemMetadataLight,locateItem,readLocatedItem}from"../core/store/item-store.js";import{resolvePmRoot}from"../core/store/paths.js";import{readSettings}from"../core/store/settings.js";import{estimatePmOutputTokens}from"./cli-contracts/agent-output-contracts.js";import{renderPmCommand}from"./command-line.js";import{createPmCliExpectedError}from"./errors.js";import{isReadOutputBudgetExceeded,normalizeReadOutputIncludeModeOptions,PM_READ_OUTPUT_SURFACE_CONTRACTS}from"./read-output-contracts.js";import{READ_OUTPUT_INVOCATION_PROVENANCE}from"./read-output/provenance.js";import{attachReadOutputContracts}from"./context-intent-contracts.js";import{attachOutputTokenAccounting}from"./output-token-accounting.js";import{assertProjectionModeChoice}from"./output-projection.js";import{assembleWorkspaceRelationshipGraph,collectDanglingDependencyReferences,resolveWorkspaceRelationshipKindRegistry}from"./graph/assembly.js";import{computeWorkspaceGraphFingerprint,workspaceGraphCache}from"./graph/cache.js";import{buildRelationshipContext,DEFAULT_RELATIONSHIP_CONTEXT_TOKEN_BUDGET}from"./relationship-context.js";import{createRelationshipKindRegistry}from"./relationships.js";const DEPS_FORMAT_VALUES=["tree","graph","context"],DEPS_COLLAPSE_VALUES=["none","repeated"],DEPS_DIRECTION_VALUES=["outgoing","incoming","both"],DEFAULT_DEPS_TREE_MAX_DEPTH=32,DEFAULT_DEPS_TREE_NODE_LIMIT=200,DEFAULT_DEPS_TREE_EDGE_LIMIT=400,DEFAULT_DEPS_TREE_TOKEN_BUDGET=16e3;function parseFormat(raw){const candidate=raw?.trim().toLowerCase()??"tree";if(DEPS_FORMAT_VALUES.includes(candidate))return candidate;throw new PmCliError(`Invalid --format value "${raw}". Use "tree", "graph", or "context".`,EXIT_CODE.USAGE)}function parsePositiveInteger(raw,flag){if(raw===void 0)return;const value=typeof raw=="number"?raw:Number(raw.trim());if(!Number.isInteger(value)||value<1)throw new PmCliError(`Invalid --${flag} value "${raw}". Use a positive integer.`,EXIT_CODE.USAGE);return value}function parseMaxDepth(raw){if(raw===void 0)return;const normalized=typeof raw=="number"?raw:Number(raw.trim());if(!Number.isInteger(normalized)||normalized<0)throw new PmCliError(`Invalid --max-depth value "${raw}". Use a non-negative integer.`,EXIT_CODE.USAGE);return normalized}function parseCollapse(raw){const candidate=raw?.trim().toLowerCase()??"none";if(DEPS_COLLAPSE_VALUES.includes(candidate))return candidate;throw new PmCliError(`Invalid --collapse value "${raw}". Use "none" or "repeated".`,EXIT_CODE.USAGE)}function parseDirection(raw){const candidate=raw?.trim().toLowerCase()??"both";if(DEPS_DIRECTION_VALUES.includes(candidate))return candidate;throw new PmCliError(`Invalid --direction value "${raw}". Use "outgoing", "incoming", or "both".`,EXIT_CODE.USAGE)}function parseKinds(raw,registry=createRelationshipKindRegistry()){if(raw===void 0)return;const values=(Array.isArray(raw)?raw:[raw]).flatMap(value=>value.split(",")).map(value=>value.trim()).filter(value=>value.length>0);if(values.length===0)return;const kinds=new Set;for(const value of values){const definition=registry.resolve(value);if(!definition){const known=registry.list().map(entry=>entry.kind).join(", ");throw new PmCliError(`Invalid --kind value "${value}". Registered kinds: ${known}.`,EXIT_CODE.USAGE)}kinds.add(definition.kind)}return[...kinds].sort()}function normalizeDependencies(dependencies){if(!dependencies||dependencies.length===0)return[];const sorted=dependencies.map(({id,kind})=>({id:id.trim(),kind:kind.trim().toLowerCase()})).sort((left,right)=>{const byKind=left.kind.localeCompare(right.kind);return byKind!==0?byKind:left.id.localeCompare(right.id)}),deduped=new Map;for(const dependency of sorted){const key=`${dependency.kind.toLowerCase()}::${dependency.id.toLowerCase()}`;deduped.has(key)||deduped.set(key,{id:dependency.id,kind:dependency.kind})}return[...deduped.values()]}function toIndexedItem(item){return{id:item.id,title:item.title,type:item.type,status:item.status,dependencies:normalizeDependencies(item.dependencies)}}function estimateTreeNodeTokens(node){return estimatePmOutputTokens(new TextEncoder().encode(JSON.stringify({...node,dependencies:void 0})).byteLength)}function appendTreeDependencies(baseNode,item,index,nextLineage,maxDepth,collapse,expanded,budget,depth){for(const dependency of item.dependencies){const edgeTokens=Math.max(1,Math.ceil(JSON.stringify({from:baseNode.id,to:dependency.id,kind:dependency.kind}).length/3));if(budget.nodes>=budget.nodeLimit){baseNode.truncated=!0,budget.reasons.add("node_limit");break}if(budget.edges>=budget.edgeLimit){baseNode.truncated=!0,budget.reasons.add("edge_limit");break}if(budget.estimatedTokens+edgeTokens>=budget.tokenBudget){baseNode.truncated=!0,budget.reasons.add("token_budget");break}budget.edges+=1,budget.estimatedTokens+=edgeTokens,baseNode.dependencies.push(toTreeNode(dependency.id,index,nextLineage,maxDepth,collapse,expanded,budget,depth+1,dependency.kind))}}function shouldStopTreeNodeExpansion(node,item,lookupId,maxDepth,collapse,expanded,budget,depth){return budget.estimatedTokens>=budget.tokenBudget&&item?.dependencies.length?(node.truncated=!0,budget.reasons.add("token_budget"),!0):!item||node.cycle?!0:maxDepth!==void 0&&depth>=maxDepth?(item.dependencies.length>0&&(node.truncated=!0,budget.reasons.add("max_depth")),!0):collapse==="repeated"&&expanded.has(lookupId)?(node.collapsed=!0,!0):!1}function toTreeNode(id,index,lineage,maxDepth,collapse,expanded,budget,depth=0,via){const lookupId=id.trim().toLowerCase(),item=index.get(lookupId),baseNode={id:item?.id??id,title:item?.title,type:item?.type,status:item?.status,via,missing:!item,cycle:lineage.has(lookupId),dependencies:[]};if(budget.nodes+=1,budget.estimatedTokens+=estimateTreeNodeTokens(baseNode),shouldStopTreeNodeExpansion(baseNode,item,lookupId,maxDepth,collapse,expanded,budget,depth))return baseNode;collapse==="repeated"&&expanded.add(lookupId);const nextLineage=new Set(lineage);return nextLineage.add(lookupId),appendTreeDependencies(baseNode,item,index,nextLineage,maxDepth,collapse,expanded,budget,depth),baseNode}function mergeGraphNode(existing,candidate){return!existing||existing.missing&&!candidate.missing?candidate:{...existing,title:existing.title??candidate.title,type:existing.type??candidate.type,status:existing.status??candidate.status}}function toGraph(root){const nodesById=new Map,edgesByKey=new Map,pending=[root];for(;pending.length>0;){const node=pending.pop();nodesById.set(node.id,mergeGraphNode(nodesById.get(node.id),{id:node.id,title:node.title,type:node.type,status:node.status,missing:node.missing}));for(const child of node.dependencies){nodesById.set(child.id,mergeGraphNode(nodesById.get(child.id),{id:child.id,title:child.title,type:child.type,status:child.status,missing:child.missing}));const relationKind=child.via??"related",edgeKey=`${node.id}::${child.id}::${relationKind}`;edgesByKey.has(edgeKey)||edgesByKey.set(edgeKey,{from:node.id,to:child.id,kind:relationKind}),child.cycle||pending.push(child)}}const nodes=[...nodesById.values()].sort((left,right)=>left.id.localeCompare(right.id)),edges=[...edgesByKey.values()].sort((left,right)=>{const byFrom=left.from.localeCompare(right.from);if(byFrom!==0)return byFrom;const byTo=left.to.localeCompare(right.to);return byTo!==0?byTo:left.kind.localeCompare(right.kind)}),missingIds=nodes.filter(node=>node.missing).map(node=>node.id);return{root_id:root.id,nodes,edges,missing_ids:missingIds}}function countDependencyGraph(rootId,index,maxDepth){const nodeIds=new Set,edgeKeys=new Set,missingIds=new Set,expanded=new Set,pending=[{id:rootId,depth:0}];let pendingIndex=0;for(;pendingIndex<pending.length;){const current=pending[pendingIndex++],lookupId=current.id.trim().toLowerCase();nodeIds.add(lookupId);const item=index.get(lookupId);if(!item){missingIds.add(lookupId);continue}if(!(maxDepth!==void 0&¤t.depth>=maxDepth)&&!expanded.has(lookupId)){expanded.add(lookupId);for(const dependency of item.dependencies)edgeKeys.add(`${lookupId}::${dependency.id.trim().toLowerCase()}::${dependency.kind}`),pending.push({id:dependency.id,depth:current.depth+1})}}return{node_count:nodeIds.size,edge_count:edgeKeys.size,edge_basis:"deduplicated_directed",missing_count:missingIds.size}}function parseDepsContextOptions(options,registry=createRelationshipKindRegistry()){const maxDepth=parseMaxDepth(options.maxDepth),nodeLimit=parsePositiveInteger(options.nodeLimit,"node-limit"),edgeLimit=parsePositiveInteger(options.edgeLimit,"edge-limit"),tokenBudget=parsePositiveInteger(options.tokenBudget,"token-budget"),kinds=parseKinds(options.kind,registry);return{direction:parseDirection(options.direction),...kinds===void 0?{}:{kinds},...maxDepth===void 0?{}:{maxDepth},...nodeLimit===void 0?{}:{nodeLimit},...edgeLimit===void 0?{}:{edgeLimit},...tokenBudget===void 0?{}:{tokenBudget},...options.cursor?.trim()?{cursor:options.cursor.trim()}:{}}}function buildContextFromAssembly(assembly,rootId,options,rootEvidence){return buildRelationshipContext(assembly.graph,rootId,assembly.details.map(detail=>detail.id===rootId&&rootEvidence.length>0?{...detail,evidence:rootEvidence}:detail),options)}function buildDepsRelationshipContext(rootId,items,options,rootEvidence=[]){const assembly=assembleWorkspaceRelationshipGraph(items);return buildContextFromAssembly(assembly,rootId,parseDepsContextOptions(options,assembly.graph.registry()),rootEvidence)}function appendEvidencePointers(evidence,label,values,limit){for(const value of values.slice(0,limit)){const trimmed=value?.trim();trimmed&&evidence.push(`${label}:${trimmed}`)}}async function collectRootEvidence(pmRoot,id,settings,typeToFolder){const located=await locateItem(pmRoot,id,settings.id_prefix,settings.item_format,typeToFolder);if(!located)return[];const{document}=await readLocatedItem(located,{schema:settings.schema}),metadata=document.metadata,files=metadata.files??[],tests=metadata.tests??[],docs=metadata.docs??[],counts=[["files",files.length],["tests",tests.length],["docs",docs.length],["comments",(metadata.comments??[]).length],["notes",(metadata.notes??[]).length],["learnings",(metadata.learnings??[]).length]];if(counts.every(([,count])=>count===0))return[];const evidence=[`linked:${counts.map(([key,count])=>`${key}=${count}`).join(",")}`];return appendEvidencePointers(evidence,"file",files.map(file=>file.path),3),appendEvidencePointers(evidence,"test",tests.map(test=>test.command??test.path),2),appendEvidencePointers(evidence,"doc",docs.map(doc=>doc.path),2),evidence}function createContextDepsResult(params){const{canonicalId,context,missingCount,missingReferences,referenceLimit,summaryOnly}=params;return{id:canonicalId,format:"context",node_count:context.nodes.length+1,edge_count:context.edges.length,edge_basis:"deduplicated_directed",missing_count:missingCount,missing_scope:"traversal",missing_reference_count:missingReferences.length,...summaryOnly?{}:{missing_references:missingReferences.slice(0,referenceLimit),context}}}function includesContextMissingReference(params){const{row,missingReachableSet,packetIds,filteredKinds,registry}=params;if(row.no_active_blocker_sentinel||!missingReachableSet.has(row.target_id.trim().toLowerCase())||!packetIds.has(row.holder_id))return!1;if(filteredKinds===void 0)return!0;const definition=registry.resolve(row.kind);return definition!==void 0&&(filteredKinds.has(definition.kind)||definition.inverse!==void 0&&filteredKinds.has(definition.inverse))}function discloseDepsOutput(result,rendering){const activeCommand=getActiveCommandContext(),commandOptions=rendering.commandOptionsOverride??(activeCommand?.command==="deps"?activeCommand.options:rendering.commandOptions);return attachReadOutputContracts("deps",{...commandOptions,...rendering.global,resolvedOutputFormat:rendering.format},result)}function renderDepsOutput(result,rendering){const disclosed=discloseDepsOutput(result,rendering),render=value=>formatBuiltInOutput(value,rendering.format,rendering.global.lean===!0);return render(rendering.global.tokenAccounting===!0?attachOutputTokenAccounting(disclosed,render):disclosed)}function settleRenderedTokenCount(result,rendering,assign){let embeddedTokens;for(;;){const measuredTokens=estimatePmOutputTokens(new TextEncoder().encode(renderDepsOutput(result,rendering)).byteLength);if(measuredTokens===embeddedTokens)return measuredTokens;assign(measuredTokens),embeddedTokens=measuredTokens}}function isContextBudgetFloorError(error){return error instanceof TypeError&&error.message.startsWith("Relationship context tokenBudget cannot fit ")}function enforceContextRenderedTokenBudget(params){const{assembly,canonicalId,contextOptions,rootEvidence,summaryOnly,rendering,missingCount,missingReferences}=params,referenceLimit=contextOptions.edgeLimit??40;let emittedReferenceLimit=Math.min(referenceLimit,missingReferences.length),internalTokenBudget=contextOptions.tokenBudget,requestedTokenBudget;for(;;){const context=buildContextFromAssembly(assembly,canonicalId,{...contextOptions,...internalTokenBudget===void 0?{}:{tokenBudget:internalTokenBudget}},rootEvidence);requestedTokenBudget??=context.meta.tokenBudget,internalTokenBudget??=requestedTokenBudget;const result=createContextDepsResult({canonicalId,context,missingCount,missingReferences,referenceLimit:emittedReferenceLimit,summaryOnly});if(summaryOnly){if(estimatePmOutputTokens(new TextEncoder().encode(renderDepsOutput(attachDepsProjection(result,!0,rendering.legacyAliasCounts),rendering)).byteLength)>requestedTokenBudget)throw new TypeError("Relationship context tokenBudget cannot fit the rendered summary");return result}if(context.meta.tokenBudget=requestedTokenBudget,context.meta.usedTokens=settleRenderedTokenCount(attachDepsProjection(result,!1,rendering.legacyAliasCounts),rendering,tokens=>{context.meta.usedTokens=tokens}),context.meta.usedTokens<=requestedTokenBudget)return result;if(emittedReferenceLimit>0){emittedReferenceLimit-=1;continue}const currentInternalBudget=internalTokenBudget,scaledInternalBudget=currentInternalBudget*requestedTokenBudget/context.meta.usedTokens;internalTokenBudget=Math.min(currentInternalBudget-1,Math.max(1,Math.floor(scaledInternalBudget*.9)))}}function createContextRetryPlan(params,budget){const options=params.contextOptions,global2={...params.rendering.global,outputFormat:params.rendering.format},args=["--pm-path",params.pmRoot,"item","deps",params.canonicalId,"--format","context","--output-format",params.rendering.format,"--token-budget"],budgetIndex=args.length;args.push(String(budget));const provided=new Set(["--pm-path","--format","--output-format","--token-budget"]),commandOptions={format:"context",tokenBudget:budget,kind:options.kinds},values=[["--max-depth","maxDepth",options.maxDepth],["--node-limit","nodeLimit",options.nodeLimit],["--edge-limit","edgeLimit",options.edgeLimit],["--direction","direction",options.direction],["--cursor","cursor",options.cursor],["--output-include","outputInclude",global2.outputInclude],["--output-limit","outputLimit",global2.outputLimit],["--output-budget","outputBudget",global2.outputBudget],["--output-session","outputSession",global2.outputSession],["--output-cursor","outputCursor",global2.outputCursor]];for(const[flag,key,value]of values)value!==void 0&&(args.push(flag,String(value)),provided.add(flag),commandOptions[key]=value);for(const kind of options.kinds??[])args.push("--kind",kind),provided.add("--kind");const booleans=[["--summary","summary",params.summaryOnly],["--full","full",params.rendering.commandOptions.full],["--json","json",global2.json],["--lean","lean",global2.lean],["--output-row-contract","outputRowContract",global2.outputRowContract],["--token-accounting","tokenAccounting",global2.tokenAccounting],["--no-extensions","noExtensions",global2.noExtensions],["--no-pager","noPager",global2.noPager]];for(const[flag,key,enabled]of booleans)enabled===!0&&(args.push(flag),provided.add(flag),commandOptions[key]=!0);const contract=PM_READ_OUTPUT_SURFACE_CONTRACTS.find(candidate=>candidate.command==="deps");return Reflect.set(commandOptions,READ_OUTPUT_INVOCATION_PROVENANCE,{canonical_include_modes:[],cli_invocation_observed:!0,explicit_legacy_aliases:Object.values(contract.dimensions).flatMap(dimension=>dimension.legacy_aliases.flatMap(alias=>provided.has(alias.flag)?[alias.flag]:[]))}),normalizeReadOutputIncludeModeOptions("deps",commandOptions),assertProjectionModeChoice(commandOptions.summary===!0,commandOptions.full===!0,"--summary"),global2.outputInclude=commandOptions.outputInclude,{args,budgetIndex,summaryOnly:commandOptions.summary===!0,rendering:{...params.rendering,global:global2,commandOptionsOverride:commandOptions}}}function probeContextRetry(params,plan,budget){const rendering={...plan.rendering,commandOptionsOverride:{...plan.rendering.commandOptionsOverride,tokenBudget:budget}};let result;try{result=enforceContextRenderedTokenBudget({...params,contextOptions:{...params.contextOptions,tokenBudget:budget},summaryOnly:plan.summaryOnly,rootEvidence:plan.summaryOnly?[]:params.rootEvidence,rendering})}catch(error){if(!isContextBudgetFloorError(error))throw error;return"native_floor"}const disclosed=discloseDepsOutput(attachDepsProjection(result,plan.summaryOnly,rendering.legacyAliasCounts),rendering);return isReadOutputBudgetExceeded(disclosed)?"output_constraints":"fits"}async function createContextBudgetRefusal(params,cause){const requested=params.contextOptions.tokenBudget??DEFAULT_RELATIONSHIP_CONTEXT_TOKEN_BUDGET,plan=createContextRetryPlan(params,requested),workUnits=(plan.summaryOnly?1:1+Math.min(params.contextOptions.edgeLimit??40,params.missingReferences.length))*(params.assembly.details.reduce((sum,node)=>sum+node.id.length+node.title.length+node.status.length+(node.type?.length??0),params.assembly.graph.edges().length+params.missingReferences.length)+(plan.summaryOnly?[]:params.rootEvidence).reduce((sum,pointer)=>sum+pointer.length,0)),{findContextBudgetRecovery}=await import("./dependencies/context-budget-recovery.js"),bounds=findContextBudgetRecovery({requested,initialBudget:DEFAULT_RELATIONSHIP_CONTEXT_TOKEN_BUDGET,workUnits,probe:budget=>probeContextRetry(params,plan,budget)}),inspectionArgs=["--pm-path",params.pmRoot,"item","deps",params.canonicalId,"--format","tree","--summary"],inspection=renderPmCommand(inspectionArgs),retryArgs=bounds.feasible_tokens===null?inspectionArgs:[...plan.args];bounds.feasible_tokens!==null&&(retryArgs[plan.budgetIndex]=String(bounds.feasible_tokens));const retry=renderPmCommand(retryArgs);return createPmCliExpectedError("Relationship context tokenBudget cannot fit the required rendered packet",{exitCode:EXIT_CODE.USAGE,cause,context:{code:"invalid_argument_value",field:"tokenBudget",value:String(requested),required:bounds.feasible_tokens===null?"Inspect the compact summary and review the output constraints.":"Retry the preserved context query with --token-budget "+bounds.feasible_tokens+".",why:"Budget advice is verified against the current query. A minimum is reported only after every smaller positive budget is checked.",examples:[retry,inspection],nextSteps:[retry],recovery:{recovery_mode:"compact",suggested_flags:["--token-budget"],token_budget:bounds,suggested_retry_args:retryArgs,suggested_retry:retry,next_best_command:inspection,fallback_candidates:[{source:"relationship_summary",command:inspection,reason:"Inspect bounded counts separately from context rows."}]}}})}async function buildContextDepsResult(params){const{pmRoot,assembly,canonicalId,options,rootEvidence,summaryOnly,rendering}=params,contextOptions=parseDepsContextOptions(options,assembly.graph.registry()),reachable=assembly.graph.closure(canonicalId,{direction:contextOptions.direction,...contextOptions.kinds===void 0?{}:{kinds:contextOptions.kinds},maxDepth:contextOptions.maxDepth??3}),missingReachable=reachable.value.filter(nodeId=>assembly.missingIdSet.has(nodeId.toLowerCase())),missingReachableSet=new Set(missingReachable.map(nodeId=>nodeId.toLowerCase())),relationshipRegistry=assembly.graph.registry(),filteredKinds=contextOptions.kinds?new Set(contextOptions.kinds.map(kind=>relationshipRegistry.require(kind).kind)):void 0,packetIds=new Set([canonicalId,...reachable.value]),missingReferences=[...assembly.dangling.active,...assembly.dangling.legacy_terminal].filter(row=>includesContextMissingReference({row,missingReachableSet,packetIds,filteredKinds,registry:relationshipRegistry})),budgetParams={pmRoot,assembly,canonicalId,contextOptions,rootEvidence,summaryOnly,rendering,missingCount:missingReachable.length,missingReferences};try{return enforceContextRenderedTokenBudget(budgetParams)}catch(error){throw isContextBudgetFloorError(error)?await createContextBudgetRefusal(budgetParams,error):error}}function trimDeepestDependency(tree){const pending=[tree];let parentToTrim;for(;pending.length>0;){const current=pending.pop();current.dependencies.length>0&&(parentToTrim=current,pending.push(...current.dependencies))}return parentToTrim?(parentToTrim.dependencies.pop(),parentToTrim.truncated=!0,!0):!1}function buildTreeOrGraphDepsResult(id,format,options,index,maxDepth,collapse,rendering){const effectiveMaxDepth=maxDepth??DEFAULT_DEPS_TREE_MAX_DEPTH,nodeLimit=parsePositiveInteger(options.nodeLimit,"node-limit")??DEFAULT_DEPS_TREE_NODE_LIMIT,edgeLimit=parsePositiveInteger(options.edgeLimit,"edge-limit")??DEFAULT_DEPS_TREE_EDGE_LIMIT,tokenBudget=parsePositiveInteger(options.tokenBudget,"token-budget")??DEFAULT_DEPS_TREE_TOKEN_BUDGET,budget={nodeLimit,edgeLimit,tokenBudget,nodes:0,edges:0,estimatedTokens:0,reasons:new Set},tree=toTreeNode(id,index,new Set,effectiveMaxDepth,format==="graph"?"repeated":collapse,new Set,budget),totals=countDependencyGraph(id,index,void 0);let result;for(;;){const graph=toGraph(tree),truncation=budget.reasons.size===0?void 0:{reasons:[...budget.reasons].sort(),limits:{max_depth:effectiveMaxDepth,node_limit:nodeLimit,edge_limit:edgeLimit,token_budget:tokenBudget},estimated_tokens:0,total_node_count:totals.node_count,total_edge_count:totals.edge_count,omitted_node_count:Math.max(0,totals.node_count-graph.nodes.length),omitted_edge_count:Math.max(0,totals.edge_count-graph.edges.length)},baseResult={id,format,node_count:graph.nodes.length,edge_count:graph.edges.length,edge_basis:"deduplicated_directed",missing_count:graph.missing_ids.length,...truncation?{truncation}:{}};if(result=format==="tree"?{...baseResult,tree}:{...baseResult,graph},(result.truncation===void 0?estimatePmOutputTokens(new TextEncoder().encode(renderDepsOutput(attachDepsProjection(result,!1,rendering.legacyAliasCounts),rendering)).byteLength):settleRenderedTokenCount(attachDepsProjection(result,!1,rendering.legacyAliasCounts),rendering,tokens=>{result.truncation.estimated_tokens=tokens}))<=tokenBudget)return result;if(!trimDeepestDependency(tree))return budget.reasons.add("token_budget"),result;budget.reasons.add("token_budget")}}function attachDepsProjection(result,summaryOnly,legacyAliasCounts={}){const group={name:result.format==="tree"?"dependency_tree":result.format==="graph"?"dependency_graph":"relationship_context",restore_with:"--full"};return{...result,legacy_alias_counts:legacyAliasCounts,projection:{mode:summaryOnly?"summary":"full",declared_field_groups:[group],included_field_groups:summaryOnly?[]:[group.name]}}}async function runDeps(id,options,global2){const pmRoot=resolvePmRoot(process.cwd(),global2.path);await assertInitializedTracker(pmRoot);const format=parseFormat(options.format),maxDepth=parseMaxDepth(options.maxDepth),collapse=parseCollapse(options.collapse);assertProjectionModeChoice(options.summary===!0,options.full===!0,"--summary");const summaryOnly=options.summary===!0,settings=await readSettings(pmRoot),typeRegistry=resolveItemTypeRegistry(settings,getActiveExtensionRegistrations()),items=await listAllItemMetadataLight(pmRoot,settings.item_format,typeRegistry.type_to_folder,void 0,settings.schema),statusRegistry=resolveRuntimeStatusRegistry(settings.schema),index=new Map(items.map(item=>[item.id.trim().toLowerCase(),toIndexedItem(item)])),dangling=collectDanglingDependencyReferences(items,status=>isTerminalStatus(status,statusRegistry));for(const reference of[...dangling.active,...dangling.legacy_terminal]){const holder=index.get(reference.holder_id.trim().toLowerCase()),referenceKind=reference.kind.trim().toLowerCase();holder&&!holder.dependencies.some(dependency=>dependency.id.trim().toLowerCase()===reference.target_id.trim().toLowerCase()&&dependency.kind===referenceKind)&&holder.dependencies.push({id:reference.target_id,kind:referenceKind})}if(!index.has(id.trim().toLowerCase()))throw new PmCliError(`Item ${id} not found`,EXIT_CODE.NOT_FOUND);const outputFormat=global2.outputFormat??(global2.json===!0||global2.json===void 0&&global2.defaultOutputFormat==="json"?"json":"toon");if(format==="context"){const canonicalId=index.get(id.trim().toLowerCase()).id,rootEvidence=summaryOnly?[]:await collectRootEvidence(pmRoot,canonicalId,settings,typeRegistry.type_to_folder),isTerminal=status=>isTerminalStatus(status,statusRegistry),relationshipRegistry=resolveWorkspaceRelationshipKindRegistry(),lookup=workspaceGraphCache().lookup(pmRoot,computeWorkspaceGraphFingerprint(items,isTerminal,relationshipRegistry),()=>assembleWorkspaceRelationshipGraph(items,isTerminal,relationshipRegistry));return attachDepsProjection(await buildContextDepsResult({pmRoot,assembly:lookup.assembly,canonicalId,options,rootEvidence,summaryOnly,rendering:{format:outputFormat,global:global2,commandOptions:options,legacyAliasCounts:lookup.assembly.legacyAliasCounts}}),summaryOnly,lookup.assembly.legacyAliasCounts)}const legacyAliasCounts=Object.fromEntries(Object.entries(assembleWorkspaceRelationshipGraph(items,status=>isTerminalStatus(status,statusRegistry)).legacyAliasCounts));return summaryOnly?attachDepsProjection({id,format,...countDependencyGraph(id,index,maxDepth)},!0,legacyAliasCounts):attachDepsProjection(buildTreeOrGraphDepsResult(id,format,options,index,maxDepth,collapse,{format:outputFormat,global:global2,commandOptions:options,legacyAliasCounts}),!1,legacyAliasCounts)}export{DEPS_COLLAPSE_VALUES,DEPS_DIRECTION_VALUES,DEPS_FORMAT_VALUES,buildDepsRelationshipContext,parseDirection,parseKinds,parseMaxDepth,parsePositiveInteger,runDeps};
|
|
2
2
|
//# sourceMappingURL=dependencies.js.map
|
package/dist/sdk/errors.d.ts
CHANGED
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
* Defines public SDK APIs and package-author helpers for Errors.
|
|
5
5
|
*/
|
|
6
6
|
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
7
|
-
import { type PmCliErrorContext } from "../core/shared/errors.js";
|
|
7
|
+
import { type PmCliErrorContext,type PmTokenBudgetRecovery } from "../core/shared/errors.js";
|
|
8
|
+
export type { PmTokenBudgetRecovery } from "../core/shared/errors.js";
|
|
9
|
+
/** Validate package-carried budget advice without trusting class identity or extra fields. */
|
|
10
|
+
export declare function isPmTokenBudgetRecovery(value:unknown):value is PmTokenBudgetRecovery;
|
|
8
11
|
/**
|
|
9
12
|
* The `Error.name` value carried by every {@link PmCliExpectedError}. The CLI's
|
|
10
13
|
* top-level handler and the Sentry crash filter recognise expected errors by
|
package/dist/sdk/errors.js
CHANGED
|
@@ -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]="cf5a7b37-5b40-52b4-a19c-18b08de649c4")}catch{}})();import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";function isPositiveSafeTokenCount(value){return typeof value=="number"&&Number.isSafeInteger(value)&&value>0}function isPmTokenBudgetRecovery(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;const candidate=value;if(!isPositiveSafeTokenCount(candidate.requested_tokens)||candidate.basis!=="canonical_retry")return!1;switch(candidate.minimum_status){case"exact":return isPositiveSafeTokenCount(candidate.minimum_feasible_tokens)&&candidate.feasible_tokens===candidate.minimum_feasible_tokens&&candidate.reason===void 0;case"feasible_only":return candidate.minimum_feasible_tokens===null&&isPositiveSafeTokenCount(candidate.feasible_tokens)&&candidate.reason===void 0;case"unavailable":return candidate.minimum_feasible_tokens===null&&candidate.feasible_tokens===null&&["query_cost_limit","search_limit","output_constraints"].includes(candidate.reason);default:return!1}}const PM_CLI_EXPECTED_ERROR_NAME="PmCliError";function isItemAlreadyExistsError(error){if(!isPmCliExpectedError(error)||error.code!=="item_already_exists"||error.exitCode!==EXIT_CODE.CONFLICT)return!1;const context=error.context;return typeof context=="object"&&context!==null&&context.code==="item_already_exists"&&typeof context.id=="string"&&context.id.trim().length>0&&typeof context.path=="string"&&context.path.trim().length>0}function normalizeExpectedErrorExitCode(value){if(!Number.isFinite(value))throw new TypeError("createPmCliExpectedError options.exitCode must be a finite number");const normalized=Math.trunc(value);if(normalized<=EXIT_CODE.SUCCESS)throw new TypeError("createPmCliExpectedError options.exitCode must be a positive exit code");return normalized}function createPmCliExpectedError(message,options={}){if(typeof message!="string"||message.trim().length===0)throw new TypeError("createPmCliExpectedError message must be a non-empty string");const error=new PmCliError(message,normalizeExpectedErrorExitCode(options.exitCode??EXIT_CODE.USAGE),options.context??{});return"cause"in options&&Object.defineProperty(error,"cause",{value:options.cause,enumerable:!1,configurable:!0,writable:!0}),error}function isPmCliExpectedError(error){if(!(error instanceof Error)||error.name!==PM_CLI_EXPECTED_ERROR_NAME)return!1;const candidate=error;return typeof candidate.exitCode=="number"&&Number.isFinite(candidate.exitCode)}export{PM_CLI_EXPECTED_ERROR_NAME,createPmCliExpectedError,isItemAlreadyExistsError,isPmCliExpectedError,isPmTokenBudgetRecovery};
|
|
2
2
|
//# sourceMappingURL=errors.js.map
|