@unbrained/pm-cli 2026.10.18 → 2026.10.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +10 -0
- package/dist/cli/help-content.js +2 -2
- package/dist/cli/register-mutation.js +2 -2
- package/dist/cli/register-setup.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +1 -1
- package/dist/cli-bundle/chunks/chunk-4CXQSRSP.js +126 -0
- package/dist/cli-bundle/chunks/{chunk-AETP4JEM.js → chunk-4ICKT4GH.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7WIEAGDS.js → chunk-4MJ6WBMA.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-4XFVAXA4.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-FIJOSX2C.js → chunk-5GZSX5HU.js} +72 -66
- package/dist/cli-bundle/chunks/{chunk-4GA4MUTE.js → chunk-6DS5CAN2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-6VZKYJW7.js → chunk-D3EDNAN7.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-DMFM5R4G.js +3 -0
- package/dist/cli-bundle/chunks/chunk-H3XYP24A.js +70 -0
- package/dist/cli-bundle/chunks/chunk-LBEMB3BW.js +6 -0
- package/dist/cli-bundle/chunks/chunk-NX7Q4LGN.js +8 -0
- package/dist/cli-bundle/chunks/chunk-O2ZRRLAP.js +8 -0
- package/dist/cli-bundle/chunks/chunk-OEJ3G7XT.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-PYRREEUB.js → chunk-QBNEZII5.js} +28 -28
- package/dist/cli-bundle/chunks/chunk-QG4LMU7A.js +112 -0
- package/dist/cli-bundle/chunks/chunk-QKAAZWGC.js +3 -0
- package/dist/cli-bundle/chunks/chunk-RUKSEZE7.js +2 -0
- package/dist/cli-bundle/chunks/chunk-TK3G3GAP.js +2 -0
- package/dist/cli-bundle/chunks/chunk-VS565KBX.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-ZZED447K.js → chunk-XH7C3A5N.js} +2 -2
- package/dist/cli-bundle/chunks/indexed-receipt-blobs-BVSHK4WQ.js +4 -0
- package/dist/cli-bundle/chunks/{register-list-query-PUCVYYBD.js → register-list-query-WQUVDJIH.js} +2 -2
- package/dist/cli-bundle/chunks/register-mutation-IWIBQIO3.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-SUWOZNDU.js +2 -0
- package/dist/cli-bundle/chunks/register-setup-QGM5YJW7.js +2 -0
- package/dist/cli-bundle/chunks/settlement-hook-UNFMCKKQ.js +7 -0
- package/dist/cli-bundle/chunks/stage-7DELI4Z5.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2MPQUMTF.js → chunk-2IEWB6MB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-3TEIACFU.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-5YTOYBTZ.js +65 -0
- package/dist/cli-bundle/focused-chunks/chunk-AK2CI2GI.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-BJMPRB7A.js +91 -0
- package/dist/cli-bundle/focused-chunks/{chunk-BFEMT5U3.js → chunk-ENZMATOY.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-EOQ6W25I.js +8 -0
- package/dist/cli-bundle/focused-chunks/{chunk-A4ZHHTEX.js → chunk-FEN7WOOP.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-FOA7XKWP.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-GWTV45SB.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZDBS2DCT.js → chunk-H6BVQ63U.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-IRVL4UXR.js → chunk-HYMYAGSY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-JBJJW2WL.js +6 -0
- package/dist/cli-bundle/focused-chunks/chunk-JCLC6HKT.js +8 -0
- package/dist/cli-bundle/focused-chunks/{chunk-TB7F4FCR.js → chunk-JDBO7SMR.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TZUIBG3P.js → chunk-KLJN44VY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-L4PL3GZR.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-OV2WVLUR.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-PXDR77TO.js +78 -0
- package/dist/cli-bundle/focused-chunks/chunk-RLRMNFLF.js +3 -0
- package/dist/cli-bundle/focused-chunks/{chunk-Z7YIFCNE.js → chunk-SKYLOPU2.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-VVRXF4JO.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-WZTEFFQI.js +3 -0
- package/dist/cli-bundle/focused-chunks/chunk-Y54ONBEX.js +25 -0
- package/dist/cli-bundle/focused-chunks/indexed-receipt-blobs-QW2VWWJE.js +4 -0
- package/dist/cli-bundle/focused-chunks/settlement-hook-X4FNHTOD.js +7 -0
- package/dist/cli-bundle/focused-chunks/stage-MZSVQYO4.js +2 -0
- package/dist/cli-bundle/main.js +3 -3
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +28 -22
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +66 -53
- 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 +2 -2
- package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +1 -0
- package/dist/sdk/cli-contracts/runtime-contracts.js +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +1 -1
- package/dist/sdk/extension/install-sources.js +3 -3
- package/dist/sdk/extension/shared.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/governance/health.js +1 -1
- package/dist/sdk/history-repair.js +1 -1
- package/dist/sdk/merge/driver.js +7 -1
- package/dist/sdk/merge/indexed-receipt-blobs.d.ts +2 -0
- package/dist/sdk/merge/indexed-receipt-blobs.js +4 -0
- package/dist/sdk/merge/install.d.ts +8 -0
- package/dist/sdk/merge/install.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +6 -0
- package/dist/sdk/merge/receipts.js +2 -2
- package/dist/sdk/merge/reconcile.d.ts +6 -0
- package/dist/sdk/merge/reconcile.js +1 -1
- package/dist/sdk/merge/settlement-hook.d.ts +12 -0
- package/dist/sdk/merge/settlement-hook.js +7 -0
- package/dist/sdk/merge/stage.d.ts +13 -0
- package/dist/sdk/merge/stage.js +2 -0
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/list.js +1 -1
- package/dist/sdk/runtime-extended-actions.js +1 -1
- package/docs/COMMANDS.md +13 -0
- package/docs/CONFIGURATION.md +14 -0
- package/docs/MERGE_SAFETY.md +88 -5
- package/docs/SDK.md +26 -0
- package/docs/TESTING.md +7 -0
- package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +6 -3
- 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-4V6ONLI6.js +0 -3
- package/dist/cli-bundle/chunks/chunk-7PATQWTH.js +0 -20
- package/dist/cli-bundle/chunks/chunk-LUKVNL72.js +0 -2
- package/dist/cli-bundle/chunks/chunk-OJ77ZQN3.js +0 -8
- package/dist/cli-bundle/chunks/chunk-RHQJ6VWC.js +0 -237
- package/dist/cli-bundle/chunks/chunk-RNABUEFB.js +0 -80
- package/dist/cli-bundle/chunks/chunk-TO6CIV4C.js +0 -2
- package/dist/cli-bundle/chunks/register-mutation-GGGVBXD5.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-NRZ6Q4QE.js +0 -2
- package/dist/cli-bundle/chunks/register-setup-MV3P3YSF.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-5UKCSZWT.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-B4YLP5ZB.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-FW7CSSKL.js +0 -75
- package/dist/cli-bundle/focused-chunks/chunk-HYPRPSYD.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-L55KQ2KT.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-MASIOFPG.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-RJ3EIHDU.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-SEL4Z2OO.js +0 -167
|
@@ -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]="099a0266-6392-5997-847e-1e8a0f24f686")}catch{}})();import{normalizeUniqueStringList}from"./string-lists.js";import{PM_TOOL_ACTIONS}from"./enum-contracts.js";import{TOOL_CREATE_OPTION_CONTRACTS,TOOL_SHARED_CREATE_UPDATE_OPTION_CONTRACTS,TOOL_UPDATE_OPTION_CONTRACTS,TOOL_UPDATE_MANY_FILTER_OPTION_CONTRACTS,TOOL_CONTEXT_OPTION_CONTRACTS,TOOL_ACTIVITY_OPTION_CONTRACTS,TOOL_LIST_FILTER_OPTION_CONTRACTS,TOOL_AGGREGATE_OPTION_CONTRACTS,TOOL_SEARCH_FILTER_OPTION_CONTRACTS,TOOL_CLOSE_MANY_FILTER_OPTION_CONTRACTS}from"./tool-option-contracts.js";import{PM_TOOL_PARAMETER_PROPERTIES as BASE_TOOL_PARAMETER_PROPERTIES,PM_TOOL_PARAMETER_METADATA as BASE_TOOL_PARAMETER_METADATA,PM_TOOL_ACTION_SCOPED_PARAMETER_PROPERTIES as BASE_ACTION_SCOPED_PARAMETER_PROPERTIES,PM_TOOL_ACTION_SCOPED_PARAMETER_METADATA,PLAN_ACTION_PARAMETER_PROPERTIES,PLAN_ACTION_PARAMETER_METADATA}from"./tool-parameter-tables.js";import{toUniqueFlagContracts,withFlagAliasMetadata}from"./flag-contracts.js";import{resolveReadOutputSurface}from"../read-output-contracts.js";const PM_TOOL_ACTION_SCOPED_PARAMETER_PROPERTIES={...BASE_ACTION_SCOPED_PARAMETER_PROPERTIES,"history-attest":{verify:{type:"object",additionalProperties:!0},output:{not:{}}}},PM_TOOL_PARAMETER_PROPERTIES={...BASE_TOOL_PARAMETER_PROPERTIES,pause:{type:"boolean"},handoff:{type:"string"},releaseAssignment:{type:"boolean"},hashAlgorithm:{type:"string",enum:["sha256","sha512"]}},PM_TOOL_PARAMETER_METADATA={...BASE_TOOL_PARAMETER_METADATA,pause:{description:"Return work to its configured open status before releasing ownership."},handoff:{description:"Release into a configured non-terminal queue with a required evidence message."},releaseAssignment:{description:"Release assignment after recording closure evidence."},hashAlgorithm:{description:"Digest for detached history bundles; defaults to sha256."}},PM_TOOL_GLOBAL_PARAMETER_KEYS=["json","quiet","profile","noExtensions","noPager","tokenAccounting","path","pmExecutable","timeoutMs"],PM_TOOL_READ_OUTPUT_PARAMETER_KEYS=["outputInclude","outputLimit","outputBudget","outputFormat","outputSession","outputCursor","outputRowContract"],PM_TOOL_RESERVED_CUSTOM_FIELD_PROPERTIES=new Set(["action","cwd","options",...Object.keys(PM_TOOL_PARAMETER_PROPERTIES).filter(property=>property!=="severity")]);function resolvePmToolCustomFieldCollision(field){const normalized=field.trim().toLowerCase();let property="";for(let index=0;index<normalized.length;index+=1){const character=normalized[index];if(character!=="-"&&character!=="_"){property+=character;continue}let nextIndex=index+1;for(;normalized[nextIndex]==="-"||normalized[nextIndex]==="_";)nextIndex+=1;const nextCharacter=normalized[nextIndex];if(nextCharacter!==void 0&&(nextCharacter>="a"&&nextCharacter<="z"||nextCharacter>="0"&&nextCharacter<="9")){property+=nextCharacter.toUpperCase(),index=nextIndex;continue}property+=normalized.slice(index,nextIndex),index=nextIndex-1}return PM_TOOL_RESERVED_CUSTOM_FIELD_PROPERTIES.has(property)?{field,property,owner:"mcp_tool_input",nested_path:`options.${property}`}:void 0}const PM_TOOL_ACTION_MUTATION_PARAMETER_KEYS={create:["fullChangedFields","idOnly"],copy:["fullChangedFields","idOnly"],update:["fullChangedFields","idOnly"],"item-reopen":["fullChangedFields","idOnly"],close:["fullChangedFields","idOnly"],claim:["fullChangedFields","idOnly"],release:["fullChangedFields","idOnly"],"start-task":["fullChangedFields","idOnly"],"pause-task":["fullChangedFields","idOnly"],"close-task":["fullChangedFields","idOnly"],restore:["fullChangedFields","idOnly"],append:["fullChangedFields"],"update-many":["fullChangedFields"],"close-many":["fullChangedFields"],assurance:["fullChangedFields","idOnly"]},PLAN_CREATE_METADATA_PARAMETER_KEYS=["createMode","status","deadline","estimate","acceptanceCriteria","definitionOfReady","order","rank","goal","objective","value","impact","outcome","whyNow","assignee","reviewer","risk","confidence","sprint","release","blockedReason","unblockNote","reporter","severity","environment","reproSteps","resolution","expectedResult","actualResult","affectedVersion","fixedVersion","component","regression","customerImpact","comment","note","learning","reminder","event","typeOption"],PM_TOOL_ACTION_NESTED_OPTION_COMPATIBILITY_KEYS=Object.freeze({"close-many":["list","expected_result","expected","actual_result","actual","validate_close","dry_run","checkpoint","no_checkpoint","filterAssignee_filter"],"update-many":["list","update","dry_run","checkpoint","no_checkpoint","filterAssignee_filter"],...Object.fromEntries(PM_TOOL_ACTIONS.filter(action=>action==="upgrade"||action==="install"||action==="extension"||action==="package"||action.startsWith("extension-")||action.startsWith("package-")).map(action=>[action,["project","local","global"]]))});function toSchemaKeyList(values){return normalizeUniqueStringList(values)}const CREATE_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_CREATE_OPTION_CONTRACTS.map(entry=>entry.param),...TOOL_SHARED_CREATE_UPDATE_OPTION_CONTRACTS.map(entry=>entry.param),"assignee","closeReason","completedAt"]),UPDATE_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_UPDATE_OPTION_CONTRACTS.map(entry=>entry.param),...TOOL_SHARED_CREATE_UPDATE_OPTION_CONTRACTS.map(entry=>entry.param),"force"]),UPDATE_MANY_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_UPDATE_MANY_FILTER_OPTION_CONTRACTS.map(entry=>entry.param),...UPDATE_CONTRACT_PARAMETER_KEYS.filter(key=>key!=="allowMissingParent"&&key!=="completedAt"),"dryRun","rollback","noCheckpoint"]),CLOSE_MANY_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_CLOSE_MANY_FILTER_OPTION_CONTRACTS.map(entry=>entry.param),"reason","completedAt","resolution","expectedResult","actualResult","validateClose","dryRun","rollback","noCheckpoint","author","message","force"]),CONTEXT_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_CONTEXT_OPTION_CONTRACTS.map(entry=>entry.param),"past","section"]),ACTIVITY_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_ACTIVITY_OPTION_CONTRACTS.map(entry=>entry.param),"stream"]),LIST_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_LIST_FILTER_OPTION_CONTRACTS.map(entry=>entry.param),"all","includeBody","noTruncate","strictRead","compact","brief","full"]),FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS=LIST_CONTRACT_PARAMETER_KEYS.filter(parameter=>parameter!=="all"&¶meter!=="status"),LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS=[[{property:"today",schema:{const:!0}},{property:"recent",schema:{const:!0}}],[{property:"today",schema:{const:!0}},{property:"updatedAfter",schema:{type:"string",pattern:"\\S"}}],[{property:"recent",schema:{const:!0}},{property:"updatedAfter",schema:{type:"string",pattern:"\\S"}}]],CONTRACTS_PROJECTION_MUTUALLY_EXCLUSIVE_GROUPS=[[{property:"summary",schema:{const:!0}},{property:"schemaOnly",schema:{const:!0}}],[{property:"summary",schema:{const:!0}},{property:"flagsOnly",schema:{const:!0}}],[{property:"summary",schema:{const:!0}},{property:"availabilityOnly",schema:{const:!0}}],[{property:"schemaOnly",schema:{const:!0}},{property:"flagsOnly",schema:{const:!0}}],[{property:"schemaOnly",schema:{const:!0}},{property:"availabilityOnly",schema:{const:!0}}],[{property:"flagsOnly",schema:{const:!0}},{property:"availabilityOnly",schema:{const:!0}}]],AGGREGATE_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_AGGREGATE_OPTION_CONTRACTS.map(entry=>entry.param),"count","completion","includeUnparented"]),SEARCH_CONTRACT_PARAMETER_KEYS=toSchemaKeyList(["query","keywords","mode","semantic","hybrid","includeLinked","titleExact","phraseExact","highlight","compact","full",...TOOL_SEARCH_FILTER_OPTION_CONTRACTS.map(entry=>entry.param)]),NEXT_CONTRACT_PARAMETER_KEYS=toSchemaKeyList(["type","tag","priority","assignee","assigneeFilter","sprint","release","parent","limit","blockedLimit","readyOnly","format","includeDecisions","includeGates","includeContainers","tokenBudget","explainRanking"]),AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS=["author","message","force"],CLOSE_ACTION_OPTION_KEYS=["releaseAssignment","text","reason","closeReason","completedAt","duplicateOf","validateClose","resolution","expectedResult","actualResult"],LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS=["author","assignee","message","force"],MANAGED_EXTENSION_PACKAGE_OPTION_KEYS=["dryRun","target","scope","capability","declarative","github","ref","init","install","uninstall","explore","manage","offline","describe","markdown","output","reload","doctor","catalog","list","adopt","adoptAll","activate","deactivate","runtimeProbe","fixManagedState","isolated","ignoreGlobal","detail","trace","watch","strictExit","failOnWarn"];function managedLifecycleSchemaContracts(prefix){return{[`${prefix}-init`]:{required:["target"],optional:["scope","capability",...prefix==="package"?["declarative"]:[]]},[`${prefix}-install`]:{optional:["target","github","scope","ref","dryRun"],anyOfRequired:[["target"],["github"]]},[`${prefix}-uninstall`]:{required:["target"],optional:["scope"]},[`${prefix}-explore`]:{optional:["scope"]},[`${prefix}-manage`]:{optional:["scope","runtimeProbe","fixManagedState","offline"]},[`${prefix}-describe`]:{optional:["target","scope","markdown","output"]},[`${prefix}-reload`]:{optional:["scope","watch"]},[`${prefix}-doctor`]:{optional:["scope","detail","trace","fixManagedState","isolated","ignoreGlobal","strictExit","failOnWarn"]},[`${prefix}-catalog`]:{optional:["scope","fields"]},[`${prefix}-adopt`]:{required:["target"],optional:["scope","github","ref"]},[`${prefix}-adopt-all`]:{optional:["scope"]},[`${prefix}-activate`]:{required:["target"],optional:["scope"]},[`${prefix}-deactivate`]:{required:["target"],optional:["scope"]},[prefix]:{optional:MANAGED_EXTENSION_PACKAGE_OPTION_KEYS,dependentAnyOfRequired:[{property:"dryRun",value:!0,anyOfRequired:[["install","target"],["install","github"]]}],mutuallyExclusiveWhen:[[{property:"dryRun",schema:{const:!0}},{property:"install",schema:{const:!1}}]]}}}const SCHEDULING_ACTION_SCHEMA_CONTRACT={required:["title"],optional:["start","duration","end","location","timezone","allDay","parent","allowMissingParent","tags","priority","body","description","author","message"]},UPGRADE_ACTION_SCHEMA_CONTRACT={optional:["target","scope","dryRun","cliOnly","packagesOnly","repair","tag","packageName"]},PM_TOOL_ACTION_SCHEMA_CONTRACTS={init:{optional:["prefix","idPrefix","workspace","preset","typePreset","defaults","author","agentGuidance","withPackages","mergeFence","force","verbose"]},config:{required:["scope","configAction"],optional:["key","value","criterion","clearCriteria","format","policy"]},...managedLifecycleSchemaContracts("extension"),...managedLifecycleSchemaContracts("package"),"package-upgrade":UPGRADE_ACTION_SCHEMA_CONTRACT,install:{optional:["target","github","scope","ref","dryRun"],anyOfRequired:[["target"],["github"]]},upgrade:UPGRADE_ACTION_SCHEMA_CONTRACT,create:{required:["title","description","type","status","priority","message"],optional:CREATE_CONTRACT_PARAMETER_KEYS},copy:{required:["id"],optional:["title","author","message","allowDuplicate"]},focus:{optional:["id","clear"],mutuallyExclusive:[["id","clear"]]},list:{optional:LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-all":{optional:LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-draft":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-open":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-in-progress":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-blocked":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-closed":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-canceled":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},aggregate:{optional:AGGREGATE_CONTRACT_PARAMETER_KEYS},guide:{optional:["list","format","depth"]},context:{optional:CONTEXT_CONTRACT_PARAMETER_KEYS},ctx:{optional:CONTEXT_CONTRACT_PARAMETER_KEYS},get:{required:["id"],optional:["for","tokenBudget","at","depth","full","fields","tree","treeDepth","format"]},search:{optional:SEARCH_CONTRACT_PARAMETER_KEYS,anyOfRequired:[["query"],["keywords"]]},eval:{optional:["mode","k","failUnder","queries","format"]},events:{optional:["since","type","author","item","limit","full","provenance","provenanceSummary","harness","agentInstance","provenanceFilter","cursorMode"]},merge:{required:["subcommand"],optional:["dryRun","author","message","force","includeReconciled","artifact","basePath","oursPath","theirsPath","output","outputPath","itemPath","prefer"]},workspace:{required:["subcommand"],optional:["snapshotAction","name","target","dryRun","force","author","message","lockTtlSeconds","lockWaitMs"],conditionalRequired:[{property:"subcommand",value:"snapshot",required:["snapshotAction"]}]},meet:SCHEDULING_ACTION_SCHEMA_CONTRACT,event:SCHEDULING_ACTION_SCHEMA_CONTRACT,remind:{required:["title"],optional:["at","text","parent","allowMissingParent","tags","priority","body","description","author","message"]},next:{optional:[...NEXT_CONTRACT_PARAMETER_KEYS,"for"]},reindex:{optional:["mode","progress"]},history:{required:["id"],optional:["limit","compact","full","provenance","provenanceSummary","harness","agentInstance","provenanceFilter","diff","verify","field","strictExit","failOnWarn","format"]},"history-attest":{optional:["verify","output","hashAlgorithm"],mutuallyExclusive:[["verify","hashAlgorithm"]]},"history-redact":{required:["id"],optional:["literal","regex","replacement","dryRun",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],anyOfRequired:[["literal"],["regex"]]},"history-repair":{optional:["id","all","dryRun","normalizeProvenance","salvageTail",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],oneOfRequired:[["id"],["all"]],mutuallyExclusiveWhen:[[{property:"salvageTail",schema:{const:!0}},{property:"all",schema:{const:!0}}],[{property:"salvageTail",schema:{const:!0}},{property:"normalizeProvenance",schema:{const:!0}}]]},"history-author-acknowledge":{optional:["historyEvent","allActionable","dryRun","planFingerprint","limit","attributedAuthor","reviewer","reason"],oneOfRequired:[["historyEvent"],["allActionable"]]},"history-compact":{optional:["id","before","ids","allOver","closed","allStreams","minEntries","dryRun",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},schema:{mutuallyExclusiveWhen:[[{property:"subcommand",schema:{const:"policy-mode"}},{property:"name",schema:{not:{enum:["advise","refuse"]}}}]],required:["subcommand"],optional:["definition","policy","message","name","description","defaultStatus","folder","alias","role","order","fieldType","commands","cliFlag","required","requiredOnCreate","allowUnset","requiredTypes","typePreset","infer","minCount","apply","to","migrationId","fieldTypeScope","dryRun","author","force"],conditionalRequired:[{property:"subcommand",value:"policy-put",required:["definition"]},{property:"subcommand",value:"policy-remove",required:["name"]},{property:"subcommand",value:"policy-mode",required:["name"]},{property:"subcommand",value:"policy-check",required:["name"]},{property:"subcommand",value:"policy-approve",required:["name","policy"]},{property:"subcommand",value:"show",required:["name"]},{property:"subcommand",value:"show-status",required:["name"]},{property:"subcommand",value:"add-type",required:["name"]},{property:"subcommand",value:"remove-type",required:["name"]},{property:"subcommand",value:"add-status",required:["name"]},{property:"subcommand",value:"remove-status",required:["name"]},{property:"subcommand",value:"add-field",required:["name"]},{property:"subcommand",value:"remove-field",required:["name"]},{property:"subcommand",value:"show-field",required:["name"]},{property:"subcommand",value:"rename-type",required:["name","to"]},{property:"subcommand",value:"rename-field",required:["name","to"]},{property:"subcommand",value:"remap-status",required:["name","to"]},{property:"subcommand",value:"apply-preset",required:["typePreset"]}]},profile:{required:["subcommand"],optional:["name","dryRun","author","force"],conditionalRequired:[{property:"subcommand",value:"show",required:["name"]},{property:"subcommand",value:"apply",required:["name"]},{property:"subcommand",value:"lint",required:["name"]}]},plan:{required:["subcommand"],optional:["id","stepRef","reorderTo","title","description","template","scope","parent","related","blocks","blockedBy","harness","mode","resumeContext","tags","priority",...PLAN_CREATE_METADATA_PARAMETER_KEYS,"body","claim","fromSearch","stepTitle","step","stepBody","stepOwner","stepStatus","stepEvidence","stepBlockedReason","stepReplacement","dependsOn","link","linkKind","linkNote","promoteToItemDep","allowMultipleActive","file","test","doc","decisionText","decision","decisionRationale","decisionEvidence","discoveryText","discovery","validationText","validation","validationCommand","validationExpected","depth","fields","steps","materializeType","materializeParent","materializeTags","field",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},activity:{optional:ACTIVITY_CONTRACT_PARAMETER_KEYS},restore:{required:["id","target"],optional:AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS},update:{required:["id"],optional:UPDATE_CONTRACT_PARAMETER_KEYS,mutuallyExclusive:[["acceptanceCriteria","addAc"],["acceptanceCriteria","removeAc"]]},"update-many":{optional:UPDATE_MANY_CONTRACT_PARAMETER_KEYS,mutuallyExclusive:[["acceptanceCriteria","addAc"],["acceptanceCriteria","removeAc"]]},close:{required:["id"],optional:[...CLOSE_ACTION_OPTION_KEYS,...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},"close-many":{optional:CLOSE_MANY_CONTRACT_PARAMETER_KEYS},delete:{required:["id"],optional:["dryRun",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},append:{required:["id","body"],optional:AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS},comments:{required:["id"],optional:["text","add","stdin","edit","delete","limit","full","ifAbsent",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],mutuallyExclusive:[["edit","ifAbsent"],["delete","ifAbsent"]]},notes:{required:["id"],optional:["text","add","addJson","stdin","edit","delete","limit","since","eventType","includeMeta","full","ifAbsent",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],mutuallyExclusive:[["addJson","add"],["addJson","stdin"],["addJson","file"],["addJson","edit"],["addJson","delete"],["edit","ifAbsent"],["delete","ifAbsent"]]},learnings:{required:["id"],optional:["text","add","stdin","edit","delete","limit","full","ifAbsent",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],mutuallyExclusive:[["edit","ifAbsent"],["delete","ifAbsent"]]},files:{required:[],optional:["id","add","addGlob","remove","migrate","list","addNote","discover","apply","discoveryNote","appendStable","validatePaths","lookupPath","scope","limit","offset","noTruncate","strictRead","explain","lines","decisionDepth",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],anyOfRequired:[["id"],["lookupPath"]],dependentAnyOfRequired:[{property:"addNote",anyOfRequired:[["add"],["addGlob"]]}]},docs:{required:["id"],optional:["add","addGlob","remove","migrate","addNote","list","validatePaths",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],dependentAnyOfRequired:[{property:"addNote",anyOfRequired:[["add"],["addGlob"]]}]},deps:{required:["id"],optional:["format","maxDepth","collapse","summary","full","nodeLimit","edgeLimit","tokenBudget","cursor","direction","kind"]},graph:{required:["subcommand"],optional:["id","target","kind","maxDepth","limit","after","direction","maxPaths","sample","exemptIsolate","exemptIsolateType","saveBaseline","rebuild","clear","summary","full"]},test:{required:["id"],optional:["list","add","addJson","remove","removeIndex","update","updateIndex","setJson","run","match","onlyIndex","onlyLast","background","timeout","progress","envSet","envClear","sharedHostSafe","pmContext","overrideLinkedPmContext","workspaceContext","overrideLinkedWorkspaceContext","allowUntrustedLinkedTests","acknowledgeLinkedTests","failOnContextMismatch","failOnSkipped","failOnEmptyTestRun","requireAssertionsForPm","checkContext","autoPmContext","measure","metricBelow","metricDiff",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],dependentAnyOfRequired:[{property:"update",anyOfRequired:[["setJson"]]},{property:"updateIndex",anyOfRequired:[["setJson"]]},{property:"setJson",anyOfRequired:[["update"],["updateIndex"]]}],mutuallyExclusive:[["update","updateIndex"],["acknowledgeLinkedTests","run"],["acknowledgeLinkedTests","background"]]},"test-all":{optional:["status","limit","offset","background","timeout","progress","envSet","envClear","sharedHostSafe","pmContext","overrideLinkedPmContext","workspaceContext","overrideLinkedWorkspaceContext","allowUntrustedLinkedTests","failOnContextMismatch","failOnSkipped","failOnEmptyTestRun","requireAssertionsForPm","checkContext","autoPmContext"]},telemetry:{optional:["subcommand","limit"]},"test-runs-list":{optional:["status","limit"]},"test-runs-status":{required:["runId"]},"test-runs-logs":{required:["runId"],optional:["stream","tail"]},"test-runs-stop":{required:["runId"],optional:["force"]},"test-runs-resume":{required:["runId"],optional:["author"]},stats:{optional:["includeEmpty","storage","metadataCoverage","fieldUtilization","byAssignee","byTag","byPriority","tagPrefix","measurements","metric","measurementLimit","observe","improvementDirection","measurementSource","measurementItem","measurementRevision","author","message","provenanceCoverage","fleetAttribution","since","eventLimit","minimumSample"]},duplicates:{optional:["status","since","threshold","limit","exhaustive"]},health:{optional:["strictDirectories","requireMergeDrivers","strictExit","failOnWarn","checkOnly","checkTelemetry","noRefresh","refreshVectors","verboseStaleItems","verboseAuthorEvents","brief","summary","skipVectors","skipIntegrity","skipDrift","full"]},validate:{optional:["checkCompleteness","checkStorageIntegrity","checkMetadata","metadataProfile","checkResolution","checkLifecycle","checkStaleBlockers","dependencyCycleSeverity","parentCycleSeverity","checkFiles","scanMode","includePmInternals","verboseFileLists","verboseDiagnostics","allAffectedIds","strictExit","failOnWarn","fixHints","autoFix","dryRun","fixScope","pruneMissing","checkHistoryDrift","checkCommandReferences","counts","full"]},assurance:{required:["subcommand"],optional:["kind","id","definition","trigger","treeId","gate","limit","dryRun","author","message","preset","owner","apply","enforcement"],conditionalRequired:[{property:"subcommand",value:"list",required:["kind"]},{property:"subcommand",value:"show",required:["kind","id"]},{property:"subcommand",value:"put",required:["kind","id","definition"]},{property:"subcommand",value:"remove",required:["kind","id"]},{property:"subcommand",value:"run",required:["id","trigger"]},{property:"subcommand",value:"apply",required:["preset","owner"]},{property:"subcommand",value:"derive",required:["owner"]},{property:"subcommand",value:"risk",required:["definition"]},{property:"subcommand",value:"lineages",required:["definition"]},{property:"subcommand",value:"promote",required:["id","enforcement"]}],mutuallyExclusiveWhen:[[{property:"subcommand",schema:{const:"risk"}},{property:"definition",schema:{not:{required:["policy","change"]}}}],[{property:"subcommand",schema:{const:"lineages"}},{property:"definition",schema:{anyOf:[{required:["change"]},{not:{required:["policy"]}}]}}]]},gc:{optional:["dryRun","gcScope"]},contracts:{optional:["contractAction","command","summary","schemaOnly","flagsOnly","availabilityOnly","runtimeOnly","activeOnly","full"],mutuallyExclusiveWhen:CONTRACTS_PROJECTION_MUTUALLY_EXCLUSIVE_GROUPS},completion:{required:["shell"],optional:["eagerTags"]},claim:{optional:["start","id","next","ifAvailable","maxAttempts","includeDecisions",...NEXT_CONTRACT_PARAMETER_KEYS,...LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],oneOfRequired:[["id"],["next"]],mutuallyExclusiveWhen:[[{property:"start",schema:{const:!0}},{property:"next",schema:{const:!0}}],[{property:"start",schema:{const:!0}},{property:"ifAvailable",schema:{const:!0}}]]},release:{required:["id"],optional:["pause","handoff",...LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],dependentAnyOfRequired:[{property:"handoff",anyOfRequired:[["message"]]}],mutuallyExclusiveWhen:[[{property:"pause",schema:{const:!0}},{property:"handoff",schema:{type:"string"}}]]},"start-task":{required:["id"],optional:LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS},"pause-task":{required:["id"],optional:LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS},"close-task":{required:["id"],optional:["text","validateClose",...LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},"item-reopen":{required:["id","reason"],optional:["status","expectedResult","author","message","force"]}},PM_TOOL_ACTION_PARAMETER_CONTRACTS=Object.freeze(Object.fromEntries(PM_TOOL_ACTIONS.map(action=>[action,PM_TOOL_ACTION_SCHEMA_CONTRACTS[action]])));function fallbackToolParameterDescription(key){return key.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[_-]/g," ").trim().replace(/^./,value=>value.toUpperCase()).concat(".")}function decorateToolParameterDefinition(key,definition){const baseDefinition=typeof definition=="object"&&definition!==null?{...definition}:{},metadata=PM_TOOL_PARAMETER_METADATA[key];return{...baseDefinition,description:metadata?.description??fallbackToolParameterDescription(key),...metadata?.examples?{examples:metadata.examples}:{}}}function actionScopedToolParameterMetadata(action,key){if(action==="history-attest"&&key==="verify")return{description:"Compare all retained history streams with a detached JSON proof object. Server-local proof paths are not accepted over MCP."};if(action==="history-attest"&&key==="output")return{description:"Local CLI/SDK only. MCP rejects this field; save the returned JSON bundle on the client."};if(action==="claim"&&key==="start")return{description:"Claim an explicit item and move it to its configured in-progress status."};if((action==="list"||action.startsWith("list-"))&&key==="all")return{description:"Return items from every lifecycle status instead of the default active-status set."};if(action==="plan"&&Object.prototype.hasOwnProperty.call(PLAN_ACTION_PARAMETER_METADATA,key))return PLAN_ACTION_PARAMETER_METADATA[key];const actionOverrides=PM_TOOL_ACTION_SCOPED_PARAMETER_METADATA[action];return actionOverrides&&Object.prototype.hasOwnProperty.call(actionOverrides,key)?actionOverrides[key]:PM_TOOL_PARAMETER_METADATA[key]}function decorateActionScopedToolParameterDefinition(action,key,definition){const baseDefinition=typeof definition=="object"&&definition!==null?{...definition}:{},metadata=actionScopedToolParameterMetadata(action,key);return{...baseDefinition,description:metadata?.description??fallbackToolParameterDescription(key),...metadata?.examples?{examples:metadata.examples}:{}}}function actionScopedToolParameterDefinition(action,key){if(action==="claim"&&key==="start")return{type:"boolean"};const actionProperties=PM_TOOL_ACTION_SCOPED_PARAMETER_PROPERTIES[action];return actionProperties&&Object.prototype.hasOwnProperty.call(actionProperties,key)?actionProperties[key]:action==="plan"&&Object.prototype.hasOwnProperty.call(PLAN_ACTION_PARAMETER_PROPERTIES,key)?PLAN_ACTION_PARAMETER_PROPERTIES[key]:(action==="get"||action==="history"||action==="search")&&key==="format"?{type:"string",enum:["json","toon"]}:key==="pause"||key==="handoff"||key==="releaseAssignment"||key==="hashAlgorithm"?PM_TOOL_PARAMETER_PROPERTIES[key]:BASE_TOOL_PARAMETER_PROPERTIES[key]}function buildActionScopedSchemaProperties(action,allowedKeys){const properties={action:{const:action,description:PM_TOOL_PARAMETER_METADATA.action?.description??"Tool action to execute."}};for(const key of allowedKeys){if(key==="action")continue;const definition=actionScopedToolParameterDefinition(action,key);definition&&(properties[key]=decorateActionScopedToolParameterDefinition(action,key,definition))}return properties}function buildOneOfSchemaEntries(action,oneOfRequiredGroups){const allOneOfFields=oneOfRequiredGroups.flat();return oneOfRequiredGroups.map(requiredFields=>{const otherFields=allOneOfFields.filter(field=>!requiredFields.includes(field));return{required:[...requiredFields],...otherFields.length>0?{not:{anyOf:otherFields.map(field=>({required:[field]}))}}:{},...action==="history-repair"&&requiredFields.includes("all")?{properties:{all:{const:!0}}}:action==="claim"&&requiredFields.includes("next")?{properties:{next:{const:!0}}}:{}}})}function schemaPropertyCondition(property,value){return{...value===void 0?{}:{properties:{[property]:{const:value}}},required:[property]}}function buildActionScopedAllOf(contract){const allOf=[];if(contract.conditionalRequired&&contract.conditionalRequired.length>0)for(const entry of contract.conditionalRequired)allOf.push({if:schemaPropertyCondition(entry.property,entry.value),then:{required:entry.required}});if(contract.dependentAnyOfRequired&&contract.dependentAnyOfRequired.length>0)for(const entry of contract.dependentAnyOfRequired)allOf.push({if:schemaPropertyCondition(entry.property,entry.value),then:{anyOf:entry.anyOfRequired.map(requiredFields=>({required:[...requiredFields]}))}});if(contract.mutuallyExclusive&&contract.mutuallyExclusive.length>0)for(const group of contract.mutuallyExclusive)allOf.push({not:{required:toSchemaKeyList(group)}});if(contract.mutuallyExclusiveWhen&&contract.mutuallyExclusiveWhen.length>0)for(const group of contract.mutuallyExclusiveWhen)allOf.push({not:{allOf:group.map(condition=>({properties:{[condition.property]:condition.schema},required:[condition.property]}))}});return allOf}function pmToolActionParameterKeys(action){if(!Object.prototype.hasOwnProperty.call(PM_TOOL_ACTION_SCHEMA_CONTRACTS,action))return;const contract=PM_TOOL_ACTION_SCHEMA_CONTRACTS[action],mutationParameterKeys=PM_TOOL_ACTION_MUTATION_PARAMETER_KEYS[action]??[];return toSchemaKeyList(["action",...PM_TOOL_GLOBAL_PARAMETER_KEYS,...resolveReadOutputSurface(action)!==void 0?PM_TOOL_READ_OUTPUT_PARAMETER_KEYS:[],...mutationParameterKeys,...contract.required??[],...contract.optional??[]])}function pmToolActionNestedOptionKeys(action){const parameterKeys=pmToolActionParameterKeys(action);if(parameterKeys!==void 0)return toSchemaKeyList([...parameterKeys,...PM_TOOL_ACTION_NESTED_OPTION_COMPATIBILITY_KEYS[action]??[]])}function buildActionScopedToolSchema(action){const contract=PM_TOOL_ACTION_SCHEMA_CONTRACTS[action],required=toSchemaKeyList(contract.required??[]),allowedKeys=pmToolActionParameterKeys(action),schema={type:"object",additionalProperties:!1,required:["action",...required],title:`pm action "${action}" parameters`,properties:buildActionScopedSchemaProperties(action,allowedKeys)};contract.anyOfRequired&&contract.anyOfRequired.length>0&&(schema.anyOf=contract.anyOfRequired.map(requiredFields=>({required:[...requiredFields]}))),contract.oneOfRequired&&contract.oneOfRequired.length>0&&(schema.oneOf=buildOneOfSchemaEntries(action,contract.oneOfRequired));const allOf=buildActionScopedAllOf(contract);return allOf.length>0&&(schema.allOf=allOf),schema}function buildPmActionToolInputSchema(action,options={}){const actionSchema=buildActionScopedToolSchema(action),actionProperties={...actionSchema.properties};delete actionProperties.action;const conditionalBranches=[...actionSchema.anyOf??[],...actionSchema.oneOf??[]],required=(options.required??actionSchema.required.map(String)).filter(key=>key==="action"?!1:options.required===void 0?!0:!conditionalBranches.some(branch=>branch.required?.map(String).includes(key))),schema={type:"object",additionalProperties:options.additionalProperties??!0,properties:{...actionProperties,options:{type:"object",additionalProperties:!0,description:"Advanced command options forwarded to the selected pm action."},...options.properties},required};return actionSchema.anyOf!==void 0&&(schema.anyOf=actionSchema.anyOf),actionSchema.oneOf!==void 0&&(schema.oneOf=actionSchema.oneOf),actionSchema.allOf!==void 0&&(schema.allOf=actionSchema.allOf),schema}function createLazyContractSchema(build){let value;const resolve=()=>value??=build();return new Proxy({},{get:(_target,prop)=>resolve()[prop],has:(_target,prop)=>prop in resolve(),ownKeys:()=>Reflect.ownKeys(resolve()),getOwnPropertyDescriptor:(_target,prop)=>{const descriptor=Reflect.getOwnPropertyDescriptor(resolve(),prop);return descriptor&&(descriptor.configurable=!0),descriptor}})}const PM_TOOL_PARAMETERS_SCHEMA_VERSION="4.22.0",PM_TOOL_PARAMETERS_SCHEMA_MAJOR=PM_TOOL_PARAMETERS_SCHEMA_VERSION.split(".")[0],PM_PROVIDER_TOOL_PARAMETERS_SCHEMA_VERSION="1.11.0",PM_TOOL_PARAMETERS_SCHEMA=createLazyContractSchema(()=>({$schema:"https://json-schema.org/draft/2020-12/schema",$id:`https://schema.unbrained.dev/pm-cli/tool-parameters-v${PM_TOOL_PARAMETERS_SCHEMA_MAJOR}.schema.json`,title:"pm-cli tool parameters (action-scoped strict schema)","x-schema-version":PM_TOOL_PARAMETERS_SCHEMA_VERSION,type:"object",oneOf:PM_TOOL_ACTIONS.map(action=>buildActionScopedToolSchema(action))}));function toProviderCompatibleParameterDefinition(key,definition){const decorated=decorateToolParameterDefinition(key,definition);if(typeof decorated.type=="string")return decorated;const firstTypedVariant=(Array.isArray(decorated.anyOf)?decorated.anyOf:[]).find(variant=>typeof variant.type=="string");if(firstTypedVariant){const{anyOf:_anyOf2,...rest2}=decorated;return{...firstTypedVariant,...rest2}}const{anyOf:_anyOf,...rest}=decorated;return{...rest,type:"string"}}function buildProviderCompatibleToolSchema(){const properties={action:{type:"string",description:PM_TOOL_PARAMETER_METADATA.action?.description??"Tool action to execute."},options:{type:"object",additionalProperties:!0,description:"Advanced command options object forwarded to the selected pm action."}};for(const key of Object.keys(PM_TOOL_PARAMETER_PROPERTIES).sort())properties[key]=toProviderCompatibleParameterDefinition(key,PM_TOOL_PARAMETER_PROPERTIES[key]);return{title:"pm-cli tool parameters (provider-compatible flat schema)","x-schema-version":PM_PROVIDER_TOOL_PARAMETERS_SCHEMA_VERSION,type:"object",additionalProperties:!1,required:["action"],properties}}const PM_PROVIDER_TOOL_PARAMETERS_SCHEMA=createLazyContractSchema(buildProviderCompatibleToolSchema),_testOnlyCliContracts={buildActionScopedToolSchema,buildProviderCompatibleToolSchema,decorateActionScopedToolParameterDefinition,decorateToolParameterDefinition,toolActionSchemaContracts:PM_TOOL_ACTION_SCHEMA_CONTRACTS,toolParameterMetadata:PM_TOOL_PARAMETER_METADATA,toProviderCompatibleParameterDefinition,toUniqueFlagContracts,withFlagAliasMetadata};export{CLOSE_ACTION_OPTION_KEYS,PLAN_CREATE_METADATA_PARAMETER_KEYS,PM_PROVIDER_TOOL_PARAMETERS_SCHEMA,PM_PROVIDER_TOOL_PARAMETERS_SCHEMA_VERSION,PM_TOOL_ACTION_PARAMETER_CONTRACTS,PM_TOOL_PARAMETERS_SCHEMA,PM_TOOL_PARAMETERS_SCHEMA_MAJOR,PM_TOOL_PARAMETERS_SCHEMA_VERSION,PM_TOOL_RESERVED_CUSTOM_FIELD_PROPERTIES,_testOnlyCliContracts,buildPmActionToolInputSchema,pmToolActionNestedOptionKeys,pmToolActionParameterKeys,resolvePmToolCustomFieldCollision};
|
|
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]="1a193d67-f078-5716-93c5-14860e38a008")}catch{}})();import{normalizeUniqueStringList}from"./string-lists.js";import{PM_TOOL_ACTIONS}from"./enum-contracts.js";import{TOOL_CREATE_OPTION_CONTRACTS,TOOL_SHARED_CREATE_UPDATE_OPTION_CONTRACTS,TOOL_UPDATE_OPTION_CONTRACTS,TOOL_UPDATE_MANY_FILTER_OPTION_CONTRACTS,TOOL_CONTEXT_OPTION_CONTRACTS,TOOL_ACTIVITY_OPTION_CONTRACTS,TOOL_LIST_FILTER_OPTION_CONTRACTS,TOOL_AGGREGATE_OPTION_CONTRACTS,TOOL_SEARCH_FILTER_OPTION_CONTRACTS,TOOL_CLOSE_MANY_FILTER_OPTION_CONTRACTS}from"./tool-option-contracts.js";import{PM_TOOL_PARAMETER_PROPERTIES as BASE_TOOL_PARAMETER_PROPERTIES,PM_TOOL_PARAMETER_METADATA as BASE_TOOL_PARAMETER_METADATA,PM_TOOL_ACTION_SCOPED_PARAMETER_PROPERTIES as BASE_ACTION_SCOPED_PARAMETER_PROPERTIES,PM_TOOL_ACTION_SCOPED_PARAMETER_METADATA,PLAN_ACTION_PARAMETER_PROPERTIES,PLAN_ACTION_PARAMETER_METADATA}from"./tool-parameter-tables.js";import{toUniqueFlagContracts,withFlagAliasMetadata}from"./flag-contracts.js";import{resolveReadOutputSurface}from"../read-output-contracts.js";const PM_TOOL_ACTION_SCOPED_PARAMETER_PROPERTIES={...BASE_ACTION_SCOPED_PARAMETER_PROPERTIES,"history-attest":{verify:{type:"object",additionalProperties:!0},output:{not:{}}}},PM_TOOL_PARAMETER_PROPERTIES={...BASE_TOOL_PARAMETER_PROPERTIES,pause:{type:"boolean"},handoff:{type:"string"},releaseAssignment:{type:"boolean"},hashAlgorithm:{type:"string",enum:["sha256","sha512"]}},PM_TOOL_PARAMETER_METADATA={...BASE_TOOL_PARAMETER_METADATA,pause:{description:"Return work to its configured open status before releasing ownership."},handoff:{description:"Release into a configured non-terminal queue with a required evidence message."},releaseAssignment:{description:"Release assignment after recording closure evidence."},hashAlgorithm:{description:"Digest for detached history bundles; defaults to sha256."}},PM_TOOL_GLOBAL_PARAMETER_KEYS=["json","quiet","profile","noExtensions","noPager","tokenAccounting","path","pmExecutable","timeoutMs"],PM_TOOL_READ_OUTPUT_PARAMETER_KEYS=["outputInclude","outputLimit","outputBudget","outputFormat","outputSession","outputCursor","outputRowContract"],PM_TOOL_RESERVED_CUSTOM_FIELD_PROPERTIES=new Set(["action","cwd","options",...Object.keys(PM_TOOL_PARAMETER_PROPERTIES).filter(property=>property!=="severity")]);function resolvePmToolCustomFieldCollision(field){const normalized=field.trim().toLowerCase();let property="";for(let index=0;index<normalized.length;index+=1){const character=normalized[index];if(character!=="-"&&character!=="_"){property+=character;continue}let nextIndex=index+1;for(;normalized[nextIndex]==="-"||normalized[nextIndex]==="_";)nextIndex+=1;const nextCharacter=normalized[nextIndex];if(nextCharacter!==void 0&&(nextCharacter>="a"&&nextCharacter<="z"||nextCharacter>="0"&&nextCharacter<="9")){property+=nextCharacter.toUpperCase(),index=nextIndex;continue}property+=normalized.slice(index,nextIndex),index=nextIndex-1}return PM_TOOL_RESERVED_CUSTOM_FIELD_PROPERTIES.has(property)?{field,property,owner:"mcp_tool_input",nested_path:`options.${property}`}:void 0}const PM_TOOL_ACTION_MUTATION_PARAMETER_KEYS={create:["fullChangedFields","idOnly"],copy:["fullChangedFields","idOnly"],update:["fullChangedFields","idOnly"],"item-reopen":["fullChangedFields","idOnly"],close:["fullChangedFields","idOnly"],claim:["fullChangedFields","idOnly"],release:["fullChangedFields","idOnly"],"start-task":["fullChangedFields","idOnly"],"pause-task":["fullChangedFields","idOnly"],"close-task":["fullChangedFields","idOnly"],restore:["fullChangedFields","idOnly"],append:["fullChangedFields"],"update-many":["fullChangedFields"],"close-many":["fullChangedFields"],assurance:["fullChangedFields","idOnly"]},PLAN_CREATE_METADATA_PARAMETER_KEYS=["createMode","status","deadline","estimate","acceptanceCriteria","definitionOfReady","order","rank","goal","objective","value","impact","outcome","whyNow","assignee","reviewer","risk","confidence","sprint","release","blockedReason","unblockNote","reporter","severity","environment","reproSteps","resolution","expectedResult","actualResult","affectedVersion","fixedVersion","component","regression","customerImpact","comment","note","learning","reminder","event","typeOption"],PM_TOOL_ACTION_NESTED_OPTION_COMPATIBILITY_KEYS=Object.freeze({"close-many":["list","expected_result","expected","actual_result","actual","validate_close","dry_run","checkpoint","no_checkpoint","filterAssignee_filter"],"update-many":["list","update","dry_run","checkpoint","no_checkpoint","filterAssignee_filter"],...Object.fromEntries(PM_TOOL_ACTIONS.filter(action=>action==="upgrade"||action==="install"||action==="extension"||action==="package"||action.startsWith("extension-")||action.startsWith("package-")).map(action=>[action,["project","local","global"]]))});function toSchemaKeyList(values){return normalizeUniqueStringList(values)}const CREATE_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_CREATE_OPTION_CONTRACTS.map(entry=>entry.param),...TOOL_SHARED_CREATE_UPDATE_OPTION_CONTRACTS.map(entry=>entry.param),"assignee","closeReason","completedAt"]),UPDATE_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_UPDATE_OPTION_CONTRACTS.map(entry=>entry.param),...TOOL_SHARED_CREATE_UPDATE_OPTION_CONTRACTS.map(entry=>entry.param),"force"]),UPDATE_MANY_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_UPDATE_MANY_FILTER_OPTION_CONTRACTS.map(entry=>entry.param),...UPDATE_CONTRACT_PARAMETER_KEYS.filter(key=>key!=="allowMissingParent"&&key!=="completedAt"),"dryRun","rollback","noCheckpoint"]),CLOSE_MANY_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_CLOSE_MANY_FILTER_OPTION_CONTRACTS.map(entry=>entry.param),"reason","completedAt","resolution","expectedResult","actualResult","validateClose","dryRun","rollback","noCheckpoint","author","message","force"]),CONTEXT_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_CONTEXT_OPTION_CONTRACTS.map(entry=>entry.param),"past","section"]),ACTIVITY_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_ACTIVITY_OPTION_CONTRACTS.map(entry=>entry.param),"stream"]),LIST_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_LIST_FILTER_OPTION_CONTRACTS.map(entry=>entry.param),"all","includeBody","noTruncate","strictRead","compact","brief","full"]),FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS=LIST_CONTRACT_PARAMETER_KEYS.filter(parameter=>parameter!=="all"&¶meter!=="status"),LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS=[[{property:"today",schema:{const:!0}},{property:"recent",schema:{const:!0}}],[{property:"today",schema:{const:!0}},{property:"updatedAfter",schema:{type:"string",pattern:"\\S"}}],[{property:"recent",schema:{const:!0}},{property:"updatedAfter",schema:{type:"string",pattern:"\\S"}}]],CONTRACTS_PROJECTION_MUTUALLY_EXCLUSIVE_GROUPS=[[{property:"summary",schema:{const:!0}},{property:"schemaOnly",schema:{const:!0}}],[{property:"summary",schema:{const:!0}},{property:"flagsOnly",schema:{const:!0}}],[{property:"summary",schema:{const:!0}},{property:"availabilityOnly",schema:{const:!0}}],[{property:"schemaOnly",schema:{const:!0}},{property:"flagsOnly",schema:{const:!0}}],[{property:"schemaOnly",schema:{const:!0}},{property:"availabilityOnly",schema:{const:!0}}],[{property:"flagsOnly",schema:{const:!0}},{property:"availabilityOnly",schema:{const:!0}}]],AGGREGATE_CONTRACT_PARAMETER_KEYS=toSchemaKeyList([...TOOL_AGGREGATE_OPTION_CONTRACTS.map(entry=>entry.param),"count","completion","includeUnparented"]),SEARCH_CONTRACT_PARAMETER_KEYS=toSchemaKeyList(["query","keywords","mode","semantic","hybrid","includeLinked","titleExact","phraseExact","highlight","compact","full",...TOOL_SEARCH_FILTER_OPTION_CONTRACTS.map(entry=>entry.param)]),NEXT_CONTRACT_PARAMETER_KEYS=toSchemaKeyList(["type","tag","priority","assignee","assigneeFilter","sprint","release","parent","limit","blockedLimit","readyOnly","format","includeDecisions","includeGates","includeContainers","tokenBudget","explainRanking"]),AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS=["author","message","force"],CLOSE_ACTION_OPTION_KEYS=["releaseAssignment","text","reason","closeReason","completedAt","duplicateOf","validateClose","resolution","expectedResult","actualResult"],LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS=["author","assignee","message","force"],MANAGED_EXTENSION_PACKAGE_OPTION_KEYS=["dryRun","target","scope","capability","declarative","github","ref","init","install","uninstall","explore","manage","offline","describe","markdown","output","reload","doctor","catalog","list","adopt","adoptAll","activate","deactivate","runtimeProbe","fixManagedState","isolated","ignoreGlobal","detail","trace","watch","strictExit","failOnWarn"];function managedLifecycleSchemaContracts(prefix){return{[`${prefix}-init`]:{required:["target"],optional:["scope","capability",...prefix==="package"?["declarative"]:[]]},[`${prefix}-install`]:{optional:["target","github","scope","ref","dryRun"],anyOfRequired:[["target"],["github"]]},[`${prefix}-uninstall`]:{required:["target"],optional:["scope"]},[`${prefix}-explore`]:{optional:["scope"]},[`${prefix}-manage`]:{optional:["scope","runtimeProbe","fixManagedState","offline"]},[`${prefix}-describe`]:{optional:["target","scope","markdown","output"]},[`${prefix}-reload`]:{optional:["scope","watch"]},[`${prefix}-doctor`]:{optional:["scope","detail","trace","fixManagedState","isolated","ignoreGlobal","strictExit","failOnWarn"]},[`${prefix}-catalog`]:{optional:["scope","fields"]},[`${prefix}-adopt`]:{required:["target"],optional:["scope","github","ref"]},[`${prefix}-adopt-all`]:{optional:["scope"]},[`${prefix}-activate`]:{required:["target"],optional:["scope"]},[`${prefix}-deactivate`]:{required:["target"],optional:["scope"]},[prefix]:{optional:MANAGED_EXTENSION_PACKAGE_OPTION_KEYS,dependentAnyOfRequired:[{property:"dryRun",value:!0,anyOfRequired:[["install","target"],["install","github"]]}],mutuallyExclusiveWhen:[[{property:"dryRun",schema:{const:!0}},{property:"install",schema:{const:!1}}]]}}}const SCHEDULING_ACTION_SCHEMA_CONTRACT={required:["title"],optional:["start","duration","end","location","timezone","allDay","parent","allowMissingParent","tags","priority","body","description","author","message"]},UPGRADE_ACTION_SCHEMA_CONTRACT={optional:["target","scope","dryRun","cliOnly","packagesOnly","repair","tag","packageName"]},PM_TOOL_ACTION_SCHEMA_CONTRACTS={init:{optional:["prefix","idPrefix","workspace","preset","typePreset","defaults","author","agentGuidance","withPackages","mergeFence","force","verbose"]},config:{required:["scope","configAction"],optional:["key","value","criterion","clearCriteria","format","policy"]},...managedLifecycleSchemaContracts("extension"),...managedLifecycleSchemaContracts("package"),"package-upgrade":UPGRADE_ACTION_SCHEMA_CONTRACT,install:{optional:["target","github","scope","ref","dryRun"],anyOfRequired:[["target"],["github"]]},upgrade:UPGRADE_ACTION_SCHEMA_CONTRACT,create:{required:["title","description","type","status","priority","message"],optional:CREATE_CONTRACT_PARAMETER_KEYS},copy:{required:["id"],optional:["title","author","message","allowDuplicate"]},focus:{optional:["id","clear"],mutuallyExclusive:[["id","clear"]]},list:{optional:LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-all":{optional:LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-draft":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-open":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-in-progress":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-blocked":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-closed":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},"list-canceled":{optional:FIXED_STATUS_LIST_CONTRACT_PARAMETER_KEYS,mutuallyExclusiveWhen:LIST_WINDOW_MUTUALLY_EXCLUSIVE_GROUPS},aggregate:{optional:AGGREGATE_CONTRACT_PARAMETER_KEYS},guide:{optional:["list","format","depth"]},context:{optional:CONTEXT_CONTRACT_PARAMETER_KEYS},ctx:{optional:CONTEXT_CONTRACT_PARAMETER_KEYS},get:{required:["id"],optional:["for","tokenBudget","at","depth","full","fields","tree","treeDepth","format"]},search:{optional:SEARCH_CONTRACT_PARAMETER_KEYS,anyOfRequired:[["query"],["keywords"]]},eval:{optional:["mode","k","failUnder","queries","format"]},events:{optional:["since","type","author","item","limit","full","provenance","provenanceSummary","harness","agentInstance","provenanceFilter","cursorMode"]},merge:{required:["subcommand"],optional:["dryRun","preCommitHook","stage","author","message","force","includeReconciled","artifact","basePath","oursPath","theirsPath","output","outputPath","itemPath","prefer"]},workspace:{required:["subcommand"],optional:["snapshotAction","name","target","dryRun","force","author","message","lockTtlSeconds","lockWaitMs"],conditionalRequired:[{property:"subcommand",value:"snapshot",required:["snapshotAction"]}]},meet:SCHEDULING_ACTION_SCHEMA_CONTRACT,event:SCHEDULING_ACTION_SCHEMA_CONTRACT,remind:{required:["title"],optional:["at","text","parent","allowMissingParent","tags","priority","body","description","author","message"]},next:{optional:[...NEXT_CONTRACT_PARAMETER_KEYS,"for"]},reindex:{optional:["mode","progress"]},history:{required:["id"],optional:["limit","compact","full","provenance","provenanceSummary","harness","agentInstance","provenanceFilter","diff","verify","field","strictExit","failOnWarn","format"]},"history-attest":{optional:["verify","output","hashAlgorithm"],mutuallyExclusive:[["verify","hashAlgorithm"]]},"history-redact":{required:["id"],optional:["literal","regex","replacement","dryRun",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],anyOfRequired:[["literal"],["regex"]]},"history-repair":{optional:["id","all","dryRun","normalizeProvenance","salvageTail",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],oneOfRequired:[["id"],["all"]],mutuallyExclusiveWhen:[[{property:"salvageTail",schema:{const:!0}},{property:"all",schema:{const:!0}}],[{property:"salvageTail",schema:{const:!0}},{property:"normalizeProvenance",schema:{const:!0}}]]},"history-author-acknowledge":{optional:["historyEvent","allActionable","dryRun","planFingerprint","limit","attributedAuthor","reviewer","reason"],oneOfRequired:[["historyEvent"],["allActionable"]]},"history-compact":{optional:["id","before","ids","allOver","closed","allStreams","minEntries","dryRun",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},schema:{mutuallyExclusiveWhen:[[{property:"subcommand",schema:{const:"policy-mode"}},{property:"name",schema:{not:{enum:["advise","refuse"]}}}]],required:["subcommand"],optional:["definition","policy","message","name","description","defaultStatus","folder","alias","role","order","fieldType","commands","cliFlag","required","requiredOnCreate","allowUnset","requiredTypes","typePreset","infer","minCount","apply","to","migrationId","fieldTypeScope","dryRun","author","force"],conditionalRequired:[{property:"subcommand",value:"policy-put",required:["definition"]},{property:"subcommand",value:"policy-remove",required:["name"]},{property:"subcommand",value:"policy-mode",required:["name"]},{property:"subcommand",value:"policy-check",required:["name"]},{property:"subcommand",value:"policy-approve",required:["name","policy"]},{property:"subcommand",value:"show",required:["name"]},{property:"subcommand",value:"show-status",required:["name"]},{property:"subcommand",value:"add-type",required:["name"]},{property:"subcommand",value:"remove-type",required:["name"]},{property:"subcommand",value:"add-status",required:["name"]},{property:"subcommand",value:"remove-status",required:["name"]},{property:"subcommand",value:"add-field",required:["name"]},{property:"subcommand",value:"remove-field",required:["name"]},{property:"subcommand",value:"show-field",required:["name"]},{property:"subcommand",value:"rename-type",required:["name","to"]},{property:"subcommand",value:"rename-field",required:["name","to"]},{property:"subcommand",value:"remap-status",required:["name","to"]},{property:"subcommand",value:"apply-preset",required:["typePreset"]}]},profile:{required:["subcommand"],optional:["name","dryRun","author","force"],conditionalRequired:[{property:"subcommand",value:"show",required:["name"]},{property:"subcommand",value:"apply",required:["name"]},{property:"subcommand",value:"lint",required:["name"]}]},plan:{required:["subcommand"],optional:["id","stepRef","reorderTo","title","description","template","scope","parent","related","blocks","blockedBy","harness","mode","resumeContext","tags","priority",...PLAN_CREATE_METADATA_PARAMETER_KEYS,"body","claim","fromSearch","stepTitle","step","stepBody","stepOwner","stepStatus","stepEvidence","stepBlockedReason","stepReplacement","dependsOn","link","linkKind","linkNote","promoteToItemDep","allowMultipleActive","file","test","doc","decisionText","decision","decisionRationale","decisionEvidence","discoveryText","discovery","validationText","validation","validationCommand","validationExpected","depth","fields","steps","materializeType","materializeParent","materializeTags","field",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},activity:{optional:ACTIVITY_CONTRACT_PARAMETER_KEYS},restore:{required:["id","target"],optional:AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS},update:{required:["id"],optional:UPDATE_CONTRACT_PARAMETER_KEYS,mutuallyExclusive:[["acceptanceCriteria","addAc"],["acceptanceCriteria","removeAc"]]},"update-many":{optional:UPDATE_MANY_CONTRACT_PARAMETER_KEYS,mutuallyExclusive:[["acceptanceCriteria","addAc"],["acceptanceCriteria","removeAc"]]},close:{required:["id"],optional:[...CLOSE_ACTION_OPTION_KEYS,...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},"close-many":{optional:CLOSE_MANY_CONTRACT_PARAMETER_KEYS},delete:{required:["id"],optional:["dryRun",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},append:{required:["id","body"],optional:AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS},comments:{required:["id"],optional:["text","add","stdin","edit","delete","limit","full","ifAbsent",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],mutuallyExclusive:[["edit","ifAbsent"],["delete","ifAbsent"]]},notes:{required:["id"],optional:["text","add","addJson","stdin","edit","delete","limit","since","eventType","includeMeta","full","ifAbsent",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],mutuallyExclusive:[["addJson","add"],["addJson","stdin"],["addJson","file"],["addJson","edit"],["addJson","delete"],["edit","ifAbsent"],["delete","ifAbsent"]]},learnings:{required:["id"],optional:["text","add","stdin","edit","delete","limit","full","ifAbsent",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],mutuallyExclusive:[["edit","ifAbsent"],["delete","ifAbsent"]]},files:{required:[],optional:["id","add","addGlob","remove","migrate","list","addNote","discover","apply","discoveryNote","appendStable","validatePaths","lookupPath","scope","limit","offset","noTruncate","strictRead","explain","lines","decisionDepth",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],anyOfRequired:[["id"],["lookupPath"]],dependentAnyOfRequired:[{property:"addNote",anyOfRequired:[["add"],["addGlob"]]}]},docs:{required:["id"],optional:["add","addGlob","remove","migrate","addNote","list","validatePaths",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],dependentAnyOfRequired:[{property:"addNote",anyOfRequired:[["add"],["addGlob"]]}]},deps:{required:["id"],optional:["format","maxDepth","collapse","summary","full","nodeLimit","edgeLimit","tokenBudget","cursor","direction","kind"]},graph:{required:["subcommand"],optional:["id","target","kind","maxDepth","limit","after","direction","maxPaths","sample","exemptIsolate","exemptIsolateType","saveBaseline","rebuild","clear","summary","full"]},test:{required:["id"],optional:["list","add","addJson","remove","removeIndex","update","updateIndex","setJson","run","match","onlyIndex","onlyLast","background","timeout","progress","envSet","envClear","sharedHostSafe","pmContext","overrideLinkedPmContext","workspaceContext","overrideLinkedWorkspaceContext","allowUntrustedLinkedTests","acknowledgeLinkedTests","failOnContextMismatch","failOnSkipped","failOnEmptyTestRun","requireAssertionsForPm","checkContext","autoPmContext","measure","metricBelow","metricDiff",...AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],dependentAnyOfRequired:[{property:"update",anyOfRequired:[["setJson"]]},{property:"updateIndex",anyOfRequired:[["setJson"]]},{property:"setJson",anyOfRequired:[["update"],["updateIndex"]]}],mutuallyExclusive:[["update","updateIndex"],["acknowledgeLinkedTests","run"],["acknowledgeLinkedTests","background"]]},"test-all":{optional:["status","limit","offset","background","timeout","progress","envSet","envClear","sharedHostSafe","pmContext","overrideLinkedPmContext","workspaceContext","overrideLinkedWorkspaceContext","allowUntrustedLinkedTests","failOnContextMismatch","failOnSkipped","failOnEmptyTestRun","requireAssertionsForPm","checkContext","autoPmContext"]},telemetry:{optional:["subcommand","limit"]},"test-runs-list":{optional:["status","limit"]},"test-runs-status":{required:["runId"]},"test-runs-logs":{required:["runId"],optional:["stream","tail"]},"test-runs-stop":{required:["runId"],optional:["force"]},"test-runs-resume":{required:["runId"],optional:["author"]},stats:{optional:["includeEmpty","storage","metadataCoverage","fieldUtilization","byAssignee","byTag","byPriority","tagPrefix","measurements","metric","measurementLimit","observe","improvementDirection","measurementSource","measurementItem","measurementRevision","author","message","provenanceCoverage","fleetAttribution","since","eventLimit","minimumSample"]},duplicates:{optional:["status","since","threshold","limit","exhaustive"]},health:{optional:["strictDirectories","requireMergeDrivers","strictExit","failOnWarn","checkOnly","checkTelemetry","noRefresh","refreshVectors","verboseStaleItems","verboseAuthorEvents","brief","summary","skipVectors","skipIntegrity","skipDrift","full"]},validate:{optional:["checkCompleteness","checkStorageIntegrity","checkMetadata","metadataProfile","checkResolution","checkLifecycle","checkStaleBlockers","dependencyCycleSeverity","parentCycleSeverity","checkFiles","scanMode","includePmInternals","verboseFileLists","verboseDiagnostics","allAffectedIds","strictExit","failOnWarn","fixHints","autoFix","dryRun","fixScope","pruneMissing","checkHistoryDrift","checkCommandReferences","counts","full"]},assurance:{required:["subcommand"],optional:["kind","id","definition","trigger","treeId","gate","limit","dryRun","author","message","preset","owner","apply","enforcement"],conditionalRequired:[{property:"subcommand",value:"list",required:["kind"]},{property:"subcommand",value:"show",required:["kind","id"]},{property:"subcommand",value:"put",required:["kind","id","definition"]},{property:"subcommand",value:"remove",required:["kind","id"]},{property:"subcommand",value:"run",required:["id","trigger"]},{property:"subcommand",value:"apply",required:["preset","owner"]},{property:"subcommand",value:"derive",required:["owner"]},{property:"subcommand",value:"risk",required:["definition"]},{property:"subcommand",value:"lineages",required:["definition"]},{property:"subcommand",value:"promote",required:["id","enforcement"]}],mutuallyExclusiveWhen:[[{property:"subcommand",schema:{const:"risk"}},{property:"definition",schema:{not:{required:["policy","change"]}}}],[{property:"subcommand",schema:{const:"lineages"}},{property:"definition",schema:{anyOf:[{required:["change"]},{not:{required:["policy"]}}]}}]]},gc:{optional:["dryRun","gcScope"]},contracts:{optional:["contractAction","command","summary","schemaOnly","flagsOnly","availabilityOnly","runtimeOnly","activeOnly","full"],mutuallyExclusiveWhen:CONTRACTS_PROJECTION_MUTUALLY_EXCLUSIVE_GROUPS},completion:{required:["shell"],optional:["eagerTags"]},claim:{optional:["start","id","next","ifAvailable","maxAttempts","includeDecisions",...NEXT_CONTRACT_PARAMETER_KEYS,...LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],oneOfRequired:[["id"],["next"]],mutuallyExclusiveWhen:[[{property:"start",schema:{const:!0}},{property:"next",schema:{const:!0}}],[{property:"start",schema:{const:!0}},{property:"ifAvailable",schema:{const:!0}}]]},release:{required:["id"],optional:["pause","handoff",...LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS],dependentAnyOfRequired:[{property:"handoff",anyOfRequired:[["message"]]}],mutuallyExclusiveWhen:[[{property:"pause",schema:{const:!0}},{property:"handoff",schema:{type:"string"}}]]},"start-task":{required:["id"],optional:LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS},"pause-task":{required:["id"],optional:LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS},"close-task":{required:["id"],optional:["text","validateClose",...LIFECYCLE_AUTHOR_MESSAGE_FORCE_PARAMETER_KEYS]},"item-reopen":{required:["id","reason"],optional:["status","expectedResult","author","message","force"]}},PM_TOOL_ACTION_PARAMETER_CONTRACTS=Object.freeze(Object.fromEntries(PM_TOOL_ACTIONS.map(action=>[action,PM_TOOL_ACTION_SCHEMA_CONTRACTS[action]])));function fallbackToolParameterDescription(key){return key.replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/[_-]/g," ").trim().replace(/^./,value=>value.toUpperCase()).concat(".")}function decorateToolParameterDefinition(key,definition){const baseDefinition=typeof definition=="object"&&definition!==null?{...definition}:{},metadata=PM_TOOL_PARAMETER_METADATA[key];return{...baseDefinition,description:metadata?.description??fallbackToolParameterDescription(key),...metadata?.examples?{examples:metadata.examples}:{}}}function actionScopedToolParameterMetadata(action,key){if(action==="history-attest"&&key==="verify")return{description:"Compare all retained history streams with a detached JSON proof object. Server-local proof paths are not accepted over MCP."};if(action==="history-attest"&&key==="output")return{description:"Local CLI/SDK only. MCP rejects this field; save the returned JSON bundle on the client."};if(action==="claim"&&key==="start")return{description:"Claim an explicit item and move it to its configured in-progress status."};if((action==="list"||action.startsWith("list-"))&&key==="all")return{description:"Return items from every lifecycle status instead of the default active-status set."};if(action==="plan"&&Object.prototype.hasOwnProperty.call(PLAN_ACTION_PARAMETER_METADATA,key))return PLAN_ACTION_PARAMETER_METADATA[key];const actionOverrides=PM_TOOL_ACTION_SCOPED_PARAMETER_METADATA[action];return actionOverrides&&Object.prototype.hasOwnProperty.call(actionOverrides,key)?actionOverrides[key]:PM_TOOL_PARAMETER_METADATA[key]}function decorateActionScopedToolParameterDefinition(action,key,definition){const baseDefinition=typeof definition=="object"&&definition!==null?{...definition}:{},metadata=actionScopedToolParameterMetadata(action,key);return{...baseDefinition,description:metadata?.description??fallbackToolParameterDescription(key),...metadata?.examples?{examples:metadata.examples}:{}}}function actionScopedToolParameterDefinition(action,key){if(action==="claim"&&key==="start")return{type:"boolean"};const actionProperties=PM_TOOL_ACTION_SCOPED_PARAMETER_PROPERTIES[action];return actionProperties&&Object.prototype.hasOwnProperty.call(actionProperties,key)?actionProperties[key]:action==="plan"&&Object.prototype.hasOwnProperty.call(PLAN_ACTION_PARAMETER_PROPERTIES,key)?PLAN_ACTION_PARAMETER_PROPERTIES[key]:(action==="get"||action==="history"||action==="search")&&key==="format"?{type:"string",enum:["json","toon"]}:key==="pause"||key==="handoff"||key==="releaseAssignment"||key==="hashAlgorithm"?PM_TOOL_PARAMETER_PROPERTIES[key]:BASE_TOOL_PARAMETER_PROPERTIES[key]}function buildActionScopedSchemaProperties(action,allowedKeys){const properties={action:{const:action,description:PM_TOOL_PARAMETER_METADATA.action?.description??"Tool action to execute."}};for(const key of allowedKeys){if(key==="action")continue;const definition=actionScopedToolParameterDefinition(action,key);definition&&(properties[key]=decorateActionScopedToolParameterDefinition(action,key,definition))}return properties}function buildOneOfSchemaEntries(action,oneOfRequiredGroups){const allOneOfFields=oneOfRequiredGroups.flat();return oneOfRequiredGroups.map(requiredFields=>{const otherFields=allOneOfFields.filter(field=>!requiredFields.includes(field));return{required:[...requiredFields],...otherFields.length>0?{not:{anyOf:otherFields.map(field=>({required:[field]}))}}:{},...action==="history-repair"&&requiredFields.includes("all")?{properties:{all:{const:!0}}}:action==="claim"&&requiredFields.includes("next")?{properties:{next:{const:!0}}}:{}}})}function schemaPropertyCondition(property,value){return{...value===void 0?{}:{properties:{[property]:{const:value}}},required:[property]}}function buildActionScopedAllOf(contract){const allOf=[];if(contract.conditionalRequired&&contract.conditionalRequired.length>0)for(const entry of contract.conditionalRequired)allOf.push({if:schemaPropertyCondition(entry.property,entry.value),then:{required:entry.required}});if(contract.dependentAnyOfRequired&&contract.dependentAnyOfRequired.length>0)for(const entry of contract.dependentAnyOfRequired)allOf.push({if:schemaPropertyCondition(entry.property,entry.value),then:{anyOf:entry.anyOfRequired.map(requiredFields=>({required:[...requiredFields]}))}});if(contract.mutuallyExclusive&&contract.mutuallyExclusive.length>0)for(const group of contract.mutuallyExclusive)allOf.push({not:{required:toSchemaKeyList(group)}});if(contract.mutuallyExclusiveWhen&&contract.mutuallyExclusiveWhen.length>0)for(const group of contract.mutuallyExclusiveWhen)allOf.push({not:{allOf:group.map(condition=>({properties:{[condition.property]:condition.schema},required:[condition.property]}))}});return allOf}function pmToolActionParameterKeys(action){if(!Object.prototype.hasOwnProperty.call(PM_TOOL_ACTION_SCHEMA_CONTRACTS,action))return;const contract=PM_TOOL_ACTION_SCHEMA_CONTRACTS[action],mutationParameterKeys=PM_TOOL_ACTION_MUTATION_PARAMETER_KEYS[action]??[];return toSchemaKeyList(["action",...PM_TOOL_GLOBAL_PARAMETER_KEYS,...resolveReadOutputSurface(action)!==void 0?PM_TOOL_READ_OUTPUT_PARAMETER_KEYS:[],...mutationParameterKeys,...contract.required??[],...contract.optional??[]])}function pmToolActionNestedOptionKeys(action){const parameterKeys=pmToolActionParameterKeys(action);if(parameterKeys!==void 0)return toSchemaKeyList([...parameterKeys,...PM_TOOL_ACTION_NESTED_OPTION_COMPATIBILITY_KEYS[action]??[]])}function buildActionScopedToolSchema(action){const contract=PM_TOOL_ACTION_SCHEMA_CONTRACTS[action],required=toSchemaKeyList(contract.required??[]),allowedKeys=pmToolActionParameterKeys(action),schema={type:"object",additionalProperties:!1,required:["action",...required],title:`pm action "${action}" parameters`,properties:buildActionScopedSchemaProperties(action,allowedKeys)};contract.anyOfRequired&&contract.anyOfRequired.length>0&&(schema.anyOf=contract.anyOfRequired.map(requiredFields=>({required:[...requiredFields]}))),contract.oneOfRequired&&contract.oneOfRequired.length>0&&(schema.oneOf=buildOneOfSchemaEntries(action,contract.oneOfRequired));const allOf=buildActionScopedAllOf(contract);return allOf.length>0&&(schema.allOf=allOf),schema}function buildPmActionToolInputSchema(action,options={}){const actionSchema=buildActionScopedToolSchema(action),actionProperties={...actionSchema.properties};delete actionProperties.action;const conditionalBranches=[...actionSchema.anyOf??[],...actionSchema.oneOf??[]],required=(options.required??actionSchema.required.map(String)).filter(key=>key==="action"?!1:options.required===void 0?!0:!conditionalBranches.some(branch=>branch.required?.map(String).includes(key))),schema={type:"object",additionalProperties:options.additionalProperties??!0,properties:{...actionProperties,options:{type:"object",additionalProperties:!0,description:"Advanced command options forwarded to the selected pm action."},...options.properties},required};return actionSchema.anyOf!==void 0&&(schema.anyOf=actionSchema.anyOf),actionSchema.oneOf!==void 0&&(schema.oneOf=actionSchema.oneOf),actionSchema.allOf!==void 0&&(schema.allOf=actionSchema.allOf),schema}function createLazyContractSchema(build){let value;const resolve=()=>value??=build();return new Proxy({},{get:(_target,prop)=>resolve()[prop],has:(_target,prop)=>prop in resolve(),ownKeys:()=>Reflect.ownKeys(resolve()),getOwnPropertyDescriptor:(_target,prop)=>{const descriptor=Reflect.getOwnPropertyDescriptor(resolve(),prop);return descriptor&&(descriptor.configurable=!0),descriptor}})}const PM_TOOL_PARAMETERS_SCHEMA_VERSION="4.22.0",PM_TOOL_PARAMETERS_SCHEMA_MAJOR=PM_TOOL_PARAMETERS_SCHEMA_VERSION.split(".")[0],PM_PROVIDER_TOOL_PARAMETERS_SCHEMA_VERSION="1.11.0",PM_TOOL_PARAMETERS_SCHEMA=createLazyContractSchema(()=>({$schema:"https://json-schema.org/draft/2020-12/schema",$id:`https://schema.unbrained.dev/pm-cli/tool-parameters-v${PM_TOOL_PARAMETERS_SCHEMA_MAJOR}.schema.json`,title:"pm-cli tool parameters (action-scoped strict schema)","x-schema-version":PM_TOOL_PARAMETERS_SCHEMA_VERSION,type:"object",oneOf:PM_TOOL_ACTIONS.map(action=>buildActionScopedToolSchema(action))}));function toProviderCompatibleParameterDefinition(key,definition){const decorated=decorateToolParameterDefinition(key,definition);if(typeof decorated.type=="string")return decorated;const firstTypedVariant=(Array.isArray(decorated.anyOf)?decorated.anyOf:[]).find(variant=>typeof variant.type=="string");if(firstTypedVariant){const{anyOf:_anyOf2,...rest2}=decorated;return{...firstTypedVariant,...rest2}}const{anyOf:_anyOf,...rest}=decorated;return{...rest,type:"string"}}function buildProviderCompatibleToolSchema(){const properties={action:{type:"string",description:PM_TOOL_PARAMETER_METADATA.action?.description??"Tool action to execute."},options:{type:"object",additionalProperties:!0,description:"Advanced command options object forwarded to the selected pm action."}};for(const key of Object.keys(PM_TOOL_PARAMETER_PROPERTIES).sort())properties[key]=toProviderCompatibleParameterDefinition(key,PM_TOOL_PARAMETER_PROPERTIES[key]);return{title:"pm-cli tool parameters (provider-compatible flat schema)","x-schema-version":PM_PROVIDER_TOOL_PARAMETERS_SCHEMA_VERSION,type:"object",additionalProperties:!1,required:["action"],properties}}const PM_PROVIDER_TOOL_PARAMETERS_SCHEMA=createLazyContractSchema(buildProviderCompatibleToolSchema),_testOnlyCliContracts={buildActionScopedToolSchema,buildProviderCompatibleToolSchema,decorateActionScopedToolParameterDefinition,decorateToolParameterDefinition,toolActionSchemaContracts:PM_TOOL_ACTION_SCHEMA_CONTRACTS,toolParameterMetadata:PM_TOOL_PARAMETER_METADATA,toProviderCompatibleParameterDefinition,toUniqueFlagContracts,withFlagAliasMetadata};export{CLOSE_ACTION_OPTION_KEYS,PLAN_CREATE_METADATA_PARAMETER_KEYS,PM_PROVIDER_TOOL_PARAMETERS_SCHEMA,PM_PROVIDER_TOOL_PARAMETERS_SCHEMA_VERSION,PM_TOOL_ACTION_PARAMETER_CONTRACTS,PM_TOOL_PARAMETERS_SCHEMA,PM_TOOL_PARAMETERS_SCHEMA_MAJOR,PM_TOOL_PARAMETERS_SCHEMA_VERSION,PM_TOOL_RESERVED_CUSTOM_FIELD_PROPERTIES,_testOnlyCliContracts,buildPmActionToolInputSchema,pmToolActionNestedOptionKeys,pmToolActionParameterKeys,resolvePmToolCustomFieldCollision};
|
|
2
2
|
//# sourceMappingURL=tool-schema.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
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]="fc993281-a2a0-59e8-9f4a-e520f1b94f3b")}catch{}})();import{execFile}from"node:child_process";import fs from"node:fs/promises";import os from"node:os";import path from"node:path";import{fileURLToPath}from"node:url";import{promisify}from"node:util";import npa from"npm-package-arg";import{extract as extractTar,list as listTar}from"tar";import{collectPackageExtensionDirectories}from"../../core/packages/manifest.js";import{resolvePmPackageRootFromModule}from"../../core/packages/root.js";import{pathExists}from"../../core/fs/fs-utils.js";import{isPathWithinDirectory}from"../../core/fs/path-utils.js";import{EXIT_CODE}from"../../core/shared/constants.js";import{PmCliError}from"../../core/shared/errors.js";import{listBundledPackageAliases}from"./bundled-catalog.js";const execFileAsync=promisify(execFile),PM_CLI_PACKAGE_NAME="@unbrained/pm-cli",LOCAL_PACKAGE_ARCHIVE_LIMITS={maxArchiveBytes:64*1024*1024,maxEntries:4096,maxExpandedBytes:256*1024*1024,maxEntryBytes:64*1024*1024};let bundledPackageAliasesCache;async function findInstalledNpmPackageCandidate(packageName,cwd=process.cwd()){const normalized=packageName.trim();if(!/^(@[^/\\\s]+\/[^/\\\s]+|[^@/\\\s][^/\\\s]*)$/u.test(normalized))return null;let current=path.resolve(cwd);for(;;){const directory=path.join(current,"node_modules",...normalized.split("/")),manifestPath=path.join(directory,"package.json");if(await pathExists(manifestPath))try{const manifest=JSON.parse(await fs.readFile(manifestPath,"utf8"));if(manifest.name===normalized)return{package:normalized,...typeof manifest.version=="string"?{version:manifest.version}:{},directory}}catch{return null}const parent=path.dirname(current);if(parent===current)return null;current=parent}}function parseGithubPathSpec(pathSpec,input,refOverride){const segments=pathSpec.split("/").map(segment=>segment.trim()).filter(segment=>segment.length>0);if(segments.length<2)return null;const owner=segments[0],repo=segments[1].replace(/\.git$/i,"");if(owner.length===0||repo.length===0)return null;const tail=segments.slice(2);let ref,subpath;return tail[0]==="tree"&&tail.length>=2?(ref=tail[1],subpath=tail.slice(2).join("/")):tail.length>0&&(subpath=tail.join("/")),typeof refOverride=="string"&&refOverride.trim().length>0&&(ref=refOverride.trim()),{kind:"github",input,owner,repo,repository:`https://github.com/${owner}/${repo}.git`,ref,subpath:subpath&&subpath.length>0?subpath:void 0}}function parseNpmInstallSource(normalizedInput,forceGithub,refOverride){const spec=normalizedInput.slice(4).trim();if(spec.length===0)throw new PmCliError('npm package source must include a package spec after "npm:".',EXIT_CODE.USAGE);if(forceGithub)throw new PmCliError('Options "--gh/--github" cannot be combined with npm: package sources.',EXIT_CODE.USAGE);if(refOverride)throw new PmCliError('Option "--ref" cannot be combined with npm: package sources.',EXIT_CODE.USAGE);return{kind:"npm",input:normalizedInput,spec}}function parseExtensionInstallSource(input,options={}){const normalizedInput=input.trim();if(normalizedInput.length===0)throw new PmCliError("Extension source is required for --install.",EXIT_CODE.USAGE);const refOverride=typeof options.ref=="string"&&options.ref.trim().length>0?options.ref.trim():void 0;if(normalizedInput.startsWith("npm:"))return parseNpmInstallSource(normalizedInput,options.forceGithub===!0,refOverride);const maybeGithubByUrl=(()=>{try{const parsed=new URL(normalizedInput);if(parsed.hostname!=="github.com")return null;const pathSpec=parsed.pathname.replace(/^\/+/,"");return parseGithubPathSpec(pathSpec,normalizedInput,refOverride)}catch{return null}})();if(maybeGithubByUrl)return maybeGithubByUrl;const strippedDomainInput=normalizedInput.startsWith("github.com/")?normalizedInput.slice(11):null;if(strippedDomainInput){const parsed=parseGithubPathSpec(strippedDomainInput,normalizedInput,refOverride);if(!parsed)throw new PmCliError(`Invalid GitHub source "${normalizedInput}".`,EXIT_CODE.USAGE);return parsed}if(options.forceGithub){const parsed=parseGithubPathSpec(normalizedInput,normalizedInput,refOverride);if(!parsed)throw new PmCliError(`Invalid GitHub shorthand "${normalizedInput}".`,EXIT_CODE.USAGE);return parsed}if(/^https?:\/\//i.test(normalizedInput))throw new PmCliError(`Unsupported extension source URL "${normalizedInput}". Supported remote source host: github.com.`,EXIT_CODE.USAGE);return{kind:"local",input:normalizedInput,absolute_path:path.resolve(process.cwd(),normalizedInput)}}async function runGitCommand(args,execRunner=execFileAsync,timeoutMs){try{return((await execRunner("git",args,{encoding:"utf8",timeout:timeoutMs})).stdout??"").trim()}catch(error){const stderr=typeof error=="object"&&error!==null&&"stderr"in error?String(error.stderr):"",message=stderr.trim().length>0?stderr.trim():error instanceof Error?error.message:String(error);throw new PmCliError(`Git command failed: git ${args.join(" ")}
|
|
2
2
|
${message}`,EXIT_CODE.GENERIC_FAILURE)}}function resolveNpmCommandName(platform=process.platform){return platform==="win32"?"npm.cmd":"npm"}function shouldRunNpmCommandInShell(platform=process.platform){return platform==="win32"}async function runNpmCommand(args,cwd,execRunner=execFileAsync,platform=process.platform,environment=process.env){const npmCommand=resolveNpmCommandName(platform),env=Object.fromEntries(Object.entries(environment).filter(([key])=>key.toLowerCase()!=="npm_config_allow_scripts"));env.NPM_CONFIG_ALLOW_SCRIPTS="";try{return((await execRunner(npmCommand,args,{cwd,encoding:"utf8",env,shell:shouldRunNpmCommandInShell(platform)})).stdout??"").trim()}catch(error){const stderr=typeof error=="object"&&error!==null&&"stderr"in error?String(error.stderr):"",message=stderr.trim().length>0?stderr.trim():error instanceof Error?error.message:String(error);throw new PmCliError(`npm command failed: ${npmCommand} ${args.join(" ")}
|
|
3
|
-
${message}`,EXIT_CODE.GENERIC_FAILURE)}}function npmPackageNameFromSpec(spec){const trimmed=spec.trim(),withoutAlias=trimmed.includes("@file:")?trimmed.slice(0,trimmed.lastIndexOf("@file:")):trimmed;return withoutAlias.startsWith("@")?withoutAlias.match(/^(@[^/@\s]+\/[^/@\s]+)/)?.[1]??withoutAlias:withoutAlias.match(/^([^/@\s]+)/)?.[1]??withoutAlias}function isNpmLocalFileAliasSpec(spec){const marker="@file:",markerIndex=spec.lastIndexOf(marker);return markerIndex>0&&spec.slice(0,markerIndex).trim().length>0&&spec.slice(markerIndex+marker.length).trim().length>0}function isNpmNotFoundError(error){const normalized=(error instanceof Error?error.message:String(error)).toLowerCase();return normalized.includes("npm err! code e404")||normalized.includes("404 not found")||normalized.includes("is not in this registry")}function isNpmPackNotFoundError(error){const normalized=(error instanceof Error?error.message:String(error)).toLowerCase();return isNpmNotFoundError(error)||normalized.includes("not found")}function isFirstPartyPmPackageName(packageName){const normalized=packageName.trim().toLowerCase();return normalized.startsWith("@unbrained/pm-")||normalized.startsWith("pm-")}function buildNpmNotFoundRecovery(spec){const packageName=npmPackageNameFromSpec(spec),isFirstPartyPackage=isFirstPartyPmPackageName(packageName),repoName=packageName.replace(/^.*\//,""),githubSource=isFirstPartyPackage?`github.com/unbraind/${repoName}`:void 0,nextBestCommand=githubSource?`pm install --project ${githubSource}`:void 0;return{message:isFirstPartyPackage?`npm package "${spec}" was not found in the registry. If this is an unpublished first-party pm package, install its GitHub repository instead.`:`npm package "${spec}" was not found in the registry.`,context:{code:"npm_package_not_found",required:"Use an install source that exists, or publish the npm package before installing it with npm:<name>.",why:"Classifying npm 404s avoids repeated registry retries and gives agents a deterministic fallback path.",examples:nextBestCommand?[nextBestCommand,"pm package catalog --project --json"]:[`npm view ${packageName}`,"pm package catalog --project --json"],nextSteps:nextBestCommand?[`Try ${nextBestCommand} if the repository exists.`,"Use pm package catalog --project --json to inspect bundled package aliases before installing."]:[`Verify ${packageName} exists in the npm registry and that you have access to it.`,"Use pm package catalog --project --json to inspect bundled package aliases before installing."],recovery:{attempted_command:`pm install --project npm:${spec}`,normalized_args:["install","--project",`npm:${spec}`],...githubSource&&nextBestCommand?{fallback_candidates:[{source:githubSource,command:nextBestCommand,reason:"canonical first-party GitHub repository fallback for unpublished pm packages"}],next_best_command:nextBestCommand}:{}}}}}function wrapNpmPackResolutionError(spec,error){if(!isNpmPackNotFoundError(error))return null;const recovery=buildNpmNotFoundRecovery(spec);return new PmCliError(recovery.message,EXIT_CODE.NOT_FOUND,recovery.context)}async function resolveLocalNpmPackagePath(spec){if(path.isAbsolute(spec)||spec.startsWith(".")||spec.startsWith("..")){const absolutePath=path.resolve(process.cwd(),spec);return await pathExists(absolutePath)?absolutePath:null}try{const parsed=new URL(spec);if(parsed.protocol==="file:"){const absolutePath=fileURLToPath(parsed);return await pathExists(absolutePath)?absolutePath:null}}catch{}if(!/^[a-z][a-z0-9+.-]*:/i.test(spec)){const absolutePath=path.resolve(process.cwd(),spec);if(await pathExists(absolutePath))return absolutePath}return null}async function resolveNpmPackSpec(spec){const localPath=await resolveLocalNpmPackagePath(spec);if(localPath)return localPath;const localFileAlias=normalizeNpmLocalFileAliasSpec(spec);return localFileAlias!==spec?localFileAlias:(/^[a-z][a-z0-9+.-]*:/i.test(spec),spec)}function normalizeNpmLocalFileAliasSpec(spec,cwd=process.cwd()){const marker="@file:",markerIndex=spec.lastIndexOf(marker);if(!isNpmLocalFileAliasSpec(spec))return spec;const packageName=spec.slice(0,markerIndex),target=spec.slice(markerIndex+marker.length);if(target.startsWith("//")&&!target.startsWith("///"))return spec;if(!target.startsWith("/"))return`${packageName}@${path.resolve(cwd,target)}`;let decodedPath;try{decodedPath=decodeURIComponent(new URL(`file:${target}`).pathname)}catch{return spec}const nativePath=/^\/[A-Za-z]:/.test(decodedPath)?decodedPath.slice(1):decodedPath;return`${packageName}@${nativePath}`}function resolvePackedTarball(packDirectory,filename){const tarball=path.resolve(packDirectory,filename),relativeTarball=path.relative(packDirectory,tarball);if(relativeTarball.length===0||relativeTarball===".."||relativeTarball.startsWith(`..${path.sep}`)||path.isAbsolute(relativeTarball))throw new PmCliError("npm pack reported a package archive outside its isolated destination.",EXIT_CODE.GENERIC_FAILURE,{code:"npm_package_archive_unsafe",required:"Retry with a trusted npm client that writes its archive inside the requested pack destination.",why:"pm will not read a package-manager artifact outside the isolated directory created for this install."});return tarball}function decodePackedNpmCandidate(value,key){if(typeof value!="object"||value===null||Array.isArray(value))return;const record=value;if(!(typeof record.filename!="string"||record.filename.trim().length===0))return{...key===void 0?{}:{key},filename:record.filename,...typeof record.name=="string"?{name:record.name}:{},...typeof record.version=="string"?{version:record.version}:{}}}function collectPackedNpmCandidates(parsed){return(Array.isArray(parsed)?parsed.map(value=>({value})):typeof parsed=="object"&&parsed!==null?Object.entries(parsed).map(([key,value])=>({key,value})):[]).flatMap(({key,value})=>{const candidate=decodePackedNpmCandidate(value,key);return candidate?[candidate]:[]})}function selectPackedNpmCandidate(candidates,expectedPackage){const normalizedExpected=expectedPackage?.trim().toLowerCase(),matchingCandidates=normalizedExpected?candidates.filter(candidate=>{const normalizedName=candidate.name?.trim().toLowerCase();return normalizedName!==void 0?normalizedName===normalizedExpected:candidate.key?.trim().toLowerCase()===normalizedExpected}):[];if(matchingCandidates.length===1)return matchingCandidates[0];if(candidates.length!==1)return;const soleCandidate=candidates[0],soleIdentity=soleCandidate.name??soleCandidate.key;return normalizedExpected&&soleIdentity!==void 0&&soleIdentity.trim().toLowerCase()!==normalizedExpected?void 0:soleCandidate}function parsePackedNpmPackage(stdout,packDirectory,expectedPackage){let parsed;try{parsed=JSON.parse(stdout)}catch{const filename=stdout.split(/\r?\n/).map(line=>line.trim()).filter(line=>line.length>0).at(-1);if(!filename)throw new PmCliError("npm pack did not report a tarball filename.",EXIT_CODE.GENERIC_FAILURE);return{tarball:resolvePackedTarball(packDirectory,filename)}}const candidates=collectPackedNpmCandidates(parsed),selected=selectPackedNpmCandidate(candidates,expectedPackage);if(!selected)throw new PmCliError("npm pack --json returned an unsupported or ambiguous package receipt.",EXIT_CODE.GENERIC_FAILURE,{code:"npm_pack_json_shape_unsupported",required:"Use an npm client that returns an array of package receipts or an object keyed by package name, with exactly one requested package entry containing filename.",why:`Well-formed JSON contained ${candidates.length} usable package receipt(s), but pm could not select ${expectedPackage??"one package"} deterministically.`});return{tarball:resolvePackedTarball(packDirectory,selected.filename),package:selected.name??selected.key,version:selected.version}}async function resolveNpmSourceDirectory(source){return resolveNpmSourceDirectoryWithRunner(source,runNpmCommand)}async function resolveNpmSourceDirectoryWithRunner(source,npmRunner){const localPackageRoot=await resolveLocalNpmPackagePath(source.spec);if(localPackageRoot){if((await fs.stat(localPackageRoot)).isFile()&&isLocalPackageArchive(localPackageRoot))return extractLocalPackageArchive(localPackageRoot);const packageJsonPath=path.join(localPackageRoot,"package.json"),packageJson=await pathExists(packageJsonPath)?JSON.parse(await fs.readFile(packageJsonPath,"utf8")):{};return{directory:await resolvePackageExtensionDirectory(localPackageRoot,source.input),package:typeof packageJson.name=="string"?packageJson.name:void 0,version:typeof packageJson.version=="string"?packageJson.version:void 0,cleanup:async()=>{}}}const tempRoot=await fs.mkdtemp(path.join(os.tmpdir(),"pm-npm-package-source-")),packDirectory=path.join(tempRoot,"pack");await fs.mkdir(packDirectory,{recursive:!0});try{const packSpec=await resolveNpmPackSpec(source.spec),packStdout=await npmRunner(["pack",packSpec,"--json","--pack-destination",packDirectory]),packed=parsePackedNpmPackage(packStdout,packDirectory,isNpmLocalFileAliasSpec(source.spec)?void 0:npmPackageNameFromSpec(source.spec));if(!await pathExists(packed.tarball))throw new PmCliError("npm pack did not create its reported package archive.",EXIT_CODE.GENERIC_FAILURE,{code:"npm_package_archive_missing",required:"Retry the npm package install with a healthy registry and writable temporary directory.",why:"The package manager reported a tarball filename that was absent before validation, so pm cannot safely extract or install it."});const extracted=await extractLocalPackageArchive(packed.tarball);return{directory:extracted.directory,package:packed.package??extracted.package,version:packed.version??extracted.version,cleanup:async()=>{try{await extracted.cleanup()}finally{await fs.rm(tempRoot,{recursive:!0,force:!0})}}}}catch(error){throw await fs.rm(tempRoot,{recursive:!0,force:!0}),wrapNpmPackResolutionError(source.spec,error)||error}}function isLocalPackageArchive(candidate){const normalized=candidate.toLowerCase();return normalized.endsWith(".tgz")||normalized.endsWith(".tar.gz")}function failLocalPackageArchive(message){throw new PmCliError(message,EXIT_CODE.USAGE,{code:"local_package_archive_unsafe",required:"Use a bounded npm .tgz or .tar.gz archive with one package/ root and no links or escaping paths.",why:"Package archives are untrusted input and must be validated before any entry reaches the filesystem."})}function validateLocalPackageArchiveEntry(entry,limits,state){if(entry.meta)return;state.entries+=1,state.entries>limits.maxEntries&&failLocalPackageArchive(`Local package archive exceeds the ${limits.maxEntries} entry limit.`);const archivePath=entry.path,segments=archivePath.split("/");(archivePath.includes("\\")||archivePath.startsWith("/")||/^[A-Za-z]:/u.test(archivePath)||segments.some(segment=>segment===".."))&&failLocalPackageArchive(`Local package archive contains an escaping path: "${archivePath}".`),segments[0]!=="package"&&failLocalPackageArchive(`Local package archive entry "${archivePath}" is outside the required package/ root.`),(entry.type==="SymbolicLink"||entry.type==="Link")&&failLocalPackageArchive(`Local package archive link "${archivePath}" is not supported.`),entry.type!=="File"&&entry.type!=="OldFile"&&entry.type!=="Directory"&&failLocalPackageArchive(`Local package archive entry "${archivePath}" uses unsupported type "${entry.type}".`),entry.size>limits.maxEntryBytes&&failLocalPackageArchive(`Local package archive entry "${archivePath}" exceeds the ${limits.maxEntryBytes} byte entry limit.`),state.expandedBytes+=entry.size,state.expandedBytes>limits.maxExpandedBytes&&failLocalPackageArchive(`Local package archive exceeds the ${limits.maxExpandedBytes} expanded byte limit.`),archivePath==="package/package.json"&&(state.packageJsonEntries+=1)}async function extractLocalPackageArchive(archivePath,limits=LOCAL_PACKAGE_ARCHIVE_LIMITS){(await fs.stat(archivePath)).size>limits.maxArchiveBytes&&failLocalPackageArchive(`Local package archive exceeds the ${limits.maxArchiveBytes} archive byte limit.`);const tempRoot=await fs.mkdtemp(path.join(os.tmpdir(),"pm-local-package-archive-")),extractDirectory=path.join(tempRoot,"extract");await fs.mkdir(extractDirectory,{recursive:!0});const state={entries:0,expandedBytes:0,packageJsonEntries:0};let validationError;try{if(await listTar({file:archivePath,strict:!0,maxDecompressionRatio:100,onReadEntry:entry=>{if(validationError===void 0)try{validateLocalPackageArchiveEntry(entry,limits,state)}catch(error){validationError=error}}}),validationError!==void 0)throw validationError;state.packageJsonEntries!==1&&failLocalPackageArchive(`Local package archive must contain exactly one package/package.json entry; found ${state.packageJsonEntries}.`),await extractTar({file:archivePath,cwd:extractDirectory,strict:!0,preservePaths:!1,preserveOwner:!1,noMtime:!0,unlink:!0,maxDepth:64,maxDecompressionRatio:100});const packageRoot=path.join(extractDirectory,"package"),packageJsonPath=path.join(packageRoot,"package.json"),packageJson=JSON.parse(await fs.readFile(packageJsonPath,"utf8"));return await installNpmPackageRuntimeDependencies(packageRoot),{directory:await resolvePackageExtensionDirectory(packageRoot,archivePath),package:typeof packageJson.name=="string"?packageJson.name:void 0,version:typeof packageJson.version=="string"?packageJson.version:void 0,cleanup:async()=>{await fs.rm(tempRoot,{recursive:!0,force:!0})}}}catch(error){throw await fs.rm(tempRoot,{recursive:!0,force:!0}),error}}async function installNpmPackageRuntimeDependencies(packageRoot,npmRunner=runNpmCommand){const packageJsonPath=path.join(packageRoot,"package.json");if(!await pathExists(packageJsonPath))return;let parsed;try{parsed=JSON.parse(await fs.readFile(packageJsonPath,"utf8"))}catch{return}if(typeof parsed!="object"||parsed===null)return;const manifest=parsed,dependencySpecs=runtimeDependencyInstallSpecs(manifest),shouldLinkHostedPmCli=hasHostedPmCliDependency(manifest);if(dependencySpecs.length===0&&!shouldLinkHostedPmCli)return;const runtimeOnlyManifest={...parsed};delete runtimeOnlyManifest.devDependencies;const installManifest={...runtimeOnlyManifest};removeHostedPmCliDependency(installManifest),await fs.writeFile(packageJsonPath,`${JSON.stringify(installManifest,null,2)}
|
|
3
|
+
${message}`,EXIT_CODE.GENERIC_FAILURE)}}function npmPackageNameFromSpec(spec){const trimmed=spec.trim(),withoutAlias=trimmed.includes("@file:")?trimmed.slice(0,trimmed.lastIndexOf("@file:")):trimmed;return withoutAlias.startsWith("@")?withoutAlias.match(/^(@[^/@\s]+\/[^/@\s]+)/)?.[1]??withoutAlias:withoutAlias.match(/^([^/@\s]+)/)?.[1]??withoutAlias}function isNpmLocalFileAliasSpec(spec){const marker="@file:",markerIndex=spec.lastIndexOf(marker);return markerIndex>0&&spec.slice(0,markerIndex).trim().length>0&&spec.slice(markerIndex+marker.length).trim().length>0}function isNpmNotFoundError(error){const normalized=(error instanceof Error?error.message:String(error)).toLowerCase();return normalized.includes("npm err! code e404")||normalized.includes("404 not found")||normalized.includes("is not in this registry")}function isNpmPackNotFoundError(error){const normalized=(error instanceof Error?error.message:String(error)).toLowerCase();return isNpmNotFoundError(error)||normalized.includes("not found")}function isFirstPartyPmPackageName(packageName){const normalized=packageName.trim().toLowerCase();return normalized.startsWith("@unbrained/pm-")||normalized.startsWith("pm-")}function buildNpmNotFoundRecovery(spec){const packageName=npmPackageNameFromSpec(spec),isFirstPartyPackage=isFirstPartyPmPackageName(packageName),repoName=packageName.replace(/^.*\//,""),githubSource=isFirstPartyPackage?`github.com/unbraind/${repoName}`:void 0,nextBestCommand=githubSource?`pm package install --project ${githubSource}`:void 0;return{message:isFirstPartyPackage?`npm package "${spec}" was not found in the registry. If this is an unpublished first-party pm package, install its GitHub repository instead.`:`npm package "${spec}" was not found in the registry.`,context:{code:"npm_package_not_found",required:"Use an install source that exists, or publish the npm package before installing it with npm:<name>.",why:"Classifying npm 404s avoids repeated registry retries and gives agents a deterministic fallback path.",examples:nextBestCommand?[nextBestCommand,"pm package catalog --project --json"]:[`npm view ${packageName}`,"pm package catalog --project --json"],nextSteps:nextBestCommand?[`Try ${nextBestCommand} if the repository exists.`,"Use pm package catalog --project --json to inspect bundled package aliases before installing."]:[`Verify ${packageName} exists in the npm registry and that you have access to it.`,"Use pm package catalog --project --json to inspect bundled package aliases before installing."],recovery:{attempted_command:`pm install --project npm:${spec}`,normalized_args:["install","--project",`npm:${spec}`],...githubSource&&nextBestCommand?{fallback_candidates:[{source:githubSource,command:nextBestCommand,reason:"canonical first-party GitHub repository fallback for unpublished pm packages"}],next_best_command:nextBestCommand}:{}}}}}function wrapNpmPackResolutionError(spec,error){if(!isNpmPackNotFoundError(error))return null;const recovery=buildNpmNotFoundRecovery(spec);return new PmCliError(recovery.message,EXIT_CODE.NOT_FOUND,recovery.context)}async function resolveLocalNpmPackagePath(spec){if(path.isAbsolute(spec)||spec.startsWith(".")||spec.startsWith("..")){const absolutePath=path.resolve(process.cwd(),spec);return await pathExists(absolutePath)?absolutePath:null}try{const parsed=new URL(spec);if(parsed.protocol==="file:"){const absolutePath=fileURLToPath(parsed);return await pathExists(absolutePath)?absolutePath:null}}catch{}if(!/^[a-z][a-z0-9+.-]*:/i.test(spec)){const absolutePath=path.resolve(process.cwd(),spec);if(await pathExists(absolutePath))return absolutePath}return null}async function resolveNpmPackSpec(spec){const localPath=await resolveLocalNpmPackagePath(spec);if(localPath)return localPath;const localFileAlias=normalizeNpmLocalFileAliasSpec(spec);return localFileAlias!==spec?localFileAlias:(/^[a-z][a-z0-9+.-]*:/i.test(spec),spec)}function normalizeNpmLocalFileAliasSpec(spec,cwd=process.cwd()){const marker="@file:",markerIndex=spec.lastIndexOf(marker);if(!isNpmLocalFileAliasSpec(spec))return spec;const packageName=spec.slice(0,markerIndex),target=spec.slice(markerIndex+marker.length);if(target.startsWith("//")&&!target.startsWith("///"))return spec;if(!target.startsWith("/"))return`${packageName}@${path.resolve(cwd,target)}`;let decodedPath;try{decodedPath=decodeURIComponent(new URL(`file:${target}`).pathname)}catch{return spec}const nativePath=/^\/[A-Za-z]:/.test(decodedPath)?decodedPath.slice(1):decodedPath;return`${packageName}@${nativePath}`}function resolvePackedTarball(packDirectory,filename){const tarball=path.resolve(packDirectory,filename),relativeTarball=path.relative(packDirectory,tarball);if(relativeTarball.length===0||relativeTarball===".."||relativeTarball.startsWith(`..${path.sep}`)||path.isAbsolute(relativeTarball))throw new PmCliError("npm pack reported a package archive outside its isolated destination.",EXIT_CODE.GENERIC_FAILURE,{code:"npm_package_archive_unsafe",required:"Retry with a trusted npm client that writes its archive inside the requested pack destination.",why:"pm will not read a package-manager artifact outside the isolated directory created for this install."});return tarball}function decodePackedNpmCandidate(value,key){if(typeof value!="object"||value===null||Array.isArray(value))return;const record=value;if(!(typeof record.filename!="string"||record.filename.trim().length===0))return{...key===void 0?{}:{key},filename:record.filename,...typeof record.name=="string"?{name:record.name}:{},...typeof record.version=="string"?{version:record.version}:{}}}function collectPackedNpmCandidates(parsed){return(Array.isArray(parsed)?parsed.map(value=>({value})):typeof parsed=="object"&&parsed!==null?Object.entries(parsed).map(([key,value])=>({key,value})):[]).flatMap(({key,value})=>{const candidate=decodePackedNpmCandidate(value,key);return candidate?[candidate]:[]})}function selectPackedNpmCandidate(candidates,expectedPackage){const normalizedExpected=expectedPackage?.trim().toLowerCase(),matchingCandidates=normalizedExpected?candidates.filter(candidate=>{const normalizedName=candidate.name?.trim().toLowerCase();return normalizedName!==void 0?normalizedName===normalizedExpected:candidate.key?.trim().toLowerCase()===normalizedExpected}):[];if(matchingCandidates.length===1)return matchingCandidates[0];if(candidates.length!==1)return;const soleCandidate=candidates[0],soleIdentity=soleCandidate.name??soleCandidate.key;return normalizedExpected&&soleIdentity!==void 0&&soleIdentity.trim().toLowerCase()!==normalizedExpected?void 0:soleCandidate}function parsePackedNpmPackage(stdout,packDirectory,expectedPackage){let parsed;try{parsed=JSON.parse(stdout)}catch{const filename=stdout.split(/\r?\n/).map(line=>line.trim()).filter(line=>line.length>0).at(-1);if(!filename)throw new PmCliError("npm pack did not report a tarball filename.",EXIT_CODE.GENERIC_FAILURE);return{tarball:resolvePackedTarball(packDirectory,filename)}}const candidates=collectPackedNpmCandidates(parsed),selected=selectPackedNpmCandidate(candidates,expectedPackage);if(!selected)throw new PmCliError("npm pack --json returned an unsupported or ambiguous package receipt.",EXIT_CODE.GENERIC_FAILURE,{code:"npm_pack_json_shape_unsupported",required:"Use an npm client that returns an array of package receipts or an object keyed by package name, with exactly one requested package entry containing filename.",why:`Well-formed JSON contained ${candidates.length} usable package receipt(s), but pm could not select ${expectedPackage??"one package"} deterministically.`});return{tarball:resolvePackedTarball(packDirectory,selected.filename),package:selected.name??selected.key,version:selected.version}}async function resolveNpmSourceDirectory(source){return resolveNpmSourceDirectoryWithRunner(source,runNpmCommand)}async function resolveNpmSourceDirectoryWithRunner(source,npmRunner){const localPackageRoot=await resolveLocalNpmPackagePath(source.spec);if(localPackageRoot){if((await fs.stat(localPackageRoot)).isFile()&&isLocalPackageArchive(localPackageRoot))return extractLocalPackageArchive(localPackageRoot);const packageJsonPath=path.join(localPackageRoot,"package.json"),packageJson=await pathExists(packageJsonPath)?JSON.parse(await fs.readFile(packageJsonPath,"utf8")):{};return{directory:await resolvePackageExtensionDirectory(localPackageRoot,source.input),package:typeof packageJson.name=="string"?packageJson.name:void 0,version:typeof packageJson.version=="string"?packageJson.version:void 0,cleanup:async()=>{}}}const tempRoot=await fs.mkdtemp(path.join(os.tmpdir(),"pm-npm-package-source-")),packDirectory=path.join(tempRoot,"pack");await fs.mkdir(packDirectory,{recursive:!0});try{const packSpec=await resolveNpmPackSpec(source.spec),packStdout=await npmRunner(["pack",packSpec,"--json","--pack-destination",packDirectory]),packed=parsePackedNpmPackage(packStdout,packDirectory,isNpmLocalFileAliasSpec(source.spec)?void 0:npmPackageNameFromSpec(source.spec));if(!await pathExists(packed.tarball))throw new PmCliError("npm pack did not create its reported package archive.",EXIT_CODE.GENERIC_FAILURE,{code:"npm_package_archive_missing",required:"Retry the npm package install with a healthy registry and writable temporary directory.",why:"The package manager reported a tarball filename that was absent before validation, so pm cannot safely extract or install it."});const extracted=await extractLocalPackageArchive(packed.tarball);return{directory:extracted.directory,package:packed.package??extracted.package,version:packed.version??extracted.version,cleanup:async()=>{try{await extracted.cleanup()}finally{await fs.rm(tempRoot,{recursive:!0,force:!0})}}}}catch(error){throw await fs.rm(tempRoot,{recursive:!0,force:!0}),wrapNpmPackResolutionError(source.spec,error)||error}}function isLocalPackageArchive(candidate){const normalized=candidate.toLowerCase();return normalized.endsWith(".tgz")||normalized.endsWith(".tar.gz")}function failLocalPackageArchive(message){throw new PmCliError(message,EXIT_CODE.USAGE,{code:"local_package_archive_unsafe",required:"Use a bounded npm .tgz or .tar.gz archive with one package/ root and no links or escaping paths.",why:"Package archives are untrusted input and must be validated before any entry reaches the filesystem."})}function validateLocalPackageArchiveEntry(entry,limits,state){if(entry.meta)return;state.entries+=1,state.entries>limits.maxEntries&&failLocalPackageArchive(`Local package archive exceeds the ${limits.maxEntries} entry limit.`);const archivePath=entry.path,segments=archivePath.split("/");(archivePath.includes("\\")||archivePath.startsWith("/")||/^[A-Za-z]:/u.test(archivePath)||segments.some(segment=>segment===".."))&&failLocalPackageArchive(`Local package archive contains an escaping path: "${archivePath}".`),segments[0]!=="package"&&failLocalPackageArchive(`Local package archive entry "${archivePath}" is outside the required package/ root.`),(entry.type==="SymbolicLink"||entry.type==="Link")&&failLocalPackageArchive(`Local package archive link "${archivePath}" is not supported.`),entry.type!=="File"&&entry.type!=="OldFile"&&entry.type!=="Directory"&&failLocalPackageArchive(`Local package archive entry "${archivePath}" uses unsupported type "${entry.type}".`),entry.size>limits.maxEntryBytes&&failLocalPackageArchive(`Local package archive entry "${archivePath}" exceeds the ${limits.maxEntryBytes} byte entry limit.`),state.expandedBytes+=entry.size,state.expandedBytes>limits.maxExpandedBytes&&failLocalPackageArchive(`Local package archive exceeds the ${limits.maxExpandedBytes} expanded byte limit.`),archivePath==="package/package.json"&&(state.packageJsonEntries+=1)}async function extractLocalPackageArchive(archivePath,limits=LOCAL_PACKAGE_ARCHIVE_LIMITS){(await fs.stat(archivePath)).size>limits.maxArchiveBytes&&failLocalPackageArchive(`Local package archive exceeds the ${limits.maxArchiveBytes} archive byte limit.`);const tempRoot=await fs.mkdtemp(path.join(os.tmpdir(),"pm-local-package-archive-")),extractDirectory=path.join(tempRoot,"extract");await fs.mkdir(extractDirectory,{recursive:!0});const state={entries:0,expandedBytes:0,packageJsonEntries:0};let validationError;try{if(await listTar({file:archivePath,strict:!0,maxDecompressionRatio:100,onReadEntry:entry=>{if(validationError===void 0)try{validateLocalPackageArchiveEntry(entry,limits,state)}catch(error){validationError=error}}}),validationError!==void 0)throw validationError;state.packageJsonEntries!==1&&failLocalPackageArchive(`Local package archive must contain exactly one package/package.json entry; found ${state.packageJsonEntries}.`),await extractTar({file:archivePath,cwd:extractDirectory,strict:!0,preservePaths:!1,preserveOwner:!1,noMtime:!0,unlink:!0,maxDepth:64,maxDecompressionRatio:100});const packageRoot=path.join(extractDirectory,"package"),packageJsonPath=path.join(packageRoot,"package.json"),packageJson=JSON.parse(await fs.readFile(packageJsonPath,"utf8"));return await installNpmPackageRuntimeDependencies(packageRoot),{directory:await resolvePackageExtensionDirectory(packageRoot,archivePath),package:typeof packageJson.name=="string"?packageJson.name:void 0,version:typeof packageJson.version=="string"?packageJson.version:void 0,cleanup:async()=>{await fs.rm(tempRoot,{recursive:!0,force:!0})}}}catch(error){throw await fs.rm(tempRoot,{recursive:!0,force:!0}),error}}async function installNpmPackageRuntimeDependencies(packageRoot,npmRunner=runNpmCommand){const packageJsonPath=path.join(packageRoot,"package.json");if(!await pathExists(packageJsonPath))return;let parsed;try{parsed=JSON.parse(await fs.readFile(packageJsonPath,"utf8"))}catch{return}if(typeof parsed!="object"||parsed===null)return;const manifest=parsed,dependencySpecs=runtimeDependencyInstallSpecs(manifest),shouldLinkHostedPmCli=hasHostedPmCliDependency(manifest);if(dependencySpecs.length===0&&!shouldLinkHostedPmCli)return;const runtimeOnlyManifest={...parsed};delete runtimeOnlyManifest.devDependencies;const installManifest={...runtimeOnlyManifest};removeHostedPmCliDependency(installManifest),await fs.writeFile(packageJsonPath,`${JSON.stringify(installManifest,null,2)}
|
|
4
4
|
`,"utf8");try{await Promise.all([fs.rm(path.join(packageRoot,"package-lock.json"),{force:!0}),fs.rm(path.join(packageRoot,"npm-shrinkwrap.json"),{force:!0})]),dependencySpecs.length>0&&await npmRunner(["install","--ignore-scripts","--no-audit","--fund=false","--package-lock=false","--no-save","--omit=peer","--"],packageRoot),shouldLinkHostedPmCli&&await linkHostedPmCliDependency(packageRoot)}finally{await fs.writeFile(packageJsonPath,`${JSON.stringify(runtimeOnlyManifest,null,2)}
|
|
5
|
-
`,"utf8")}}function hasHostedPmCliDependency(manifest){for(const dependencyMap of[manifest.dependencies,manifest.optionalDependencies,manifest.peerDependencies])if(typeof dependencyMap=="object"&&dependencyMap!==null&&PM_CLI_PACKAGE_NAME in dependencyMap)return!0;return!1}function removeHostedPmCliDependency(manifest){for(const field of["dependencies","optionalDependencies","peerDependencies"]){const dependencyMap=manifest[field];if(typeof dependencyMap!="object"||dependencyMap===null)continue;const nextMap={...dependencyMap};delete nextMap[PM_CLI_PACKAGE_NAME],Object.keys(nextMap).length===0?delete manifest[field]:manifest[field]=nextMap}}async function linkHostedPmCliDependency(packageRoot){const hostPackageRoot=resolvePmPackageRootFromModule(import.meta.url,["../../.."]),[scope,packageName]=PM_CLI_PACKAGE_NAME.split("/"),scopedDirectory=path.join(packageRoot,"node_modules",scope),linkPath=path.join(scopedDirectory,packageName);await fs.mkdir(scopedDirectory,{recursive:!0}),await fs.rm(linkPath,{recursive:!0,force:!0}),await fs.symlink(hostPackageRoot,linkPath,resolveDirectorySymlinkType(process.platform))}function resolveDirectorySymlinkType(platform){return platform==="win32"?"junction":"dir"}function validateRuntimeDependencySpec(name,version){if(name.startsWith("-"))throw new PmCliError(`Extension runtime dependency name "${name}" is unsafe because npm could interpret it as a command-line option.`,EXIT_CODE.USAGE,{code:"extension_dependency_name_unsafe",required:"Use a valid npm package name that does not begin with a dash.",why:"Extension manifests are untrusted input and dependency names must never become npm options."});if([...version].some(character=>{const codePoint=character.charCodeAt(0);return codePoint<=31||codePoint===127||"&|;()`\"'".includes(character)}))throw new PmCliError(`Extension runtime dependency "${name}" has an unsafe version specifier.`,EXIT_CODE.USAGE,{code:"extension_dependency_version_unsafe",required:"Use an npm version, range, dist-tag, URL, or file specifier without shell metacharacters.",why:"npm.cmd requires a command shell on Windows, so untrusted shell metacharacters cannot be forwarded."});try{npa.resolve(name,version)}catch{throw new PmCliError(`Extension runtime dependency "${name}@${version}" is not a valid npm dependency specifier.`,EXIT_CODE.USAGE,{code:"extension_dependency_spec_invalid",required:"Use a valid npm package name and npm-supported version, range, dist-tag, URL, or file specifier.",why:"Only grammar-validated dependency specs may be written to the isolated runtime install manifest."})}return`${name}@${version}`}function runtimeDependencyInstallSpecs(manifest){const specs=new Map;for(const dependencyMap of[manifest.dependencies,manifest.optionalDependencies,manifest.peerDependencies])if(!(typeof dependencyMap!="object"||dependencyMap===null))for(const[name,version]of Object.entries(dependencyMap)){if(name===PM_CLI_PACKAGE_NAME||typeof version!="string"||version.trim().length===0||specs.has(name))continue;const normalizedVersion=version.trim();specs.set(name,validateRuntimeDependencySpec(name,normalizedVersion))}return[...specs.values()]}async function resolvePackageExtensionDirectory(packageRoot,sourceLabel){const discovered=await collectPackageExtensionDirectories(packageRoot);if(discovered.length===1)return discovered[0];if(discovered.length>1){const choices=discovered.map(entry=>path.relative(packageRoot,entry).replaceAll(path.sep,"/")).sort((left,right)=>left.localeCompare(right));throw new PmCliError(`Package source "${sourceLabel}" contains multiple extension manifests. Provide an explicit extension path. Candidates: ${choices.join(", ")}`,EXIT_CODE.USAGE)}throw new PmCliError(`Unable to locate a pm extension manifest in package source "${sourceLabel}". Package installs currently activate only extension resources, so add package.json pm.extensions or an extensions/ directory. Metadata-only resources like pm.docs/pm.examples are catalog metadata and do not activate commands.`,EXIT_CODE.USAGE)}async function resolveGithubSourceDirectory(cloneDirectory,source){const candidatePaths=[];source.subpath&&(candidatePaths.push(source.subpath),candidatePaths.push(path.posix.join(".agents/pm/extensions",source.subpath)),candidatePaths.push(path.posix.join(".custom/pm-extensions",source.subpath)),candidatePaths.push(path.posix.join(".custom/pm-extension",source.subpath)));for(const candidate of candidatePaths){const absolute=path.resolve(cloneDirectory,candidate);if(isPathWithinDirectory(cloneDirectory,absolute)&&await pathExists(path.join(absolute,"manifest.json")))return{directory:absolute,resolved_subpath:candidate}}if(await pathExists(path.join(cloneDirectory,"manifest.json")))return{directory:cloneDirectory,resolved_subpath:"."};const discoveredDirectory=await resolvePackageExtensionDirectory(cloneDirectory,source.input);return{directory:discoveredDirectory,resolved_subpath:path.relative(cloneDirectory,discoveredDirectory).replaceAll(path.sep,"/")}}function looksLikeBarePackageName(input){const trimmed=input.trim();return trimmed.length===0||trimmed.startsWith(".")||trimmed.startsWith("~")?!1:trimmed.startsWith("@")?trimmed.split("/").length===2:!trimmed.includes("/")&&!trimmed.includes("\\")}async function buildLocalSourceNotFoundError(source){const baseMessage=`Local extension source does not exist: "${source.absolute_path}".`,input=source.input.trim();if(!looksLikeBarePackageName(input))return new PmCliError(baseMessage,EXIT_CODE.NOT_FOUND);let bundledAliases=[];try{const envPackageRoot=process.env.PM_CLI_PACKAGE_ROOT,cacheKey=typeof envPackageRoot=="string"&&envPackageRoot.trim().length>0?path.resolve(envPackageRoot.trim()):"";bundledPackageAliasesCache?.key!==cacheKey&&(bundledPackageAliasesCache={key:cacheKey,aliases:await listBundledPackageAliases()}),bundledAliases=bundledPackageAliasesCache.aliases}catch{}const nextSteps=[`Retry with pm install npm:${input} if the package is published to npm.`,`Or inspect bundled packages with pm package catalog --project --json before installing by alias. Known aliases (blank means none found): ${bundledAliases.join(", ")}`];return new PmCliError(`${baseMessage} "${input}" did not match a local directory, bundled package alias, or bundled package name; if you meant an npm package, install it as "npm:${input}".`,EXIT_CODE.NOT_FOUND,{code:"local_source_not_found_bare_name",required:`Use "npm:${input}" for npm registry packages, a bundled catalog alias, or an existing local directory path.`,why:"Bare names resolve as local paths only after bundled aliases, so unmatched names need an explicit npm: source.",examples:[`pm install npm:${input}`,"pm package catalog --project --json"],nextSteps,recovery:{attempted_command:`pm install ${input}`,normalized_args:["install",input],next_best_command:`pm install npm:${input}`}})}async function resolveInstallSource(source){if(source.kind==="local"){let localStats;try{localStats=await fs.stat(source.absolute_path)}catch{throw await buildLocalSourceNotFoundError(source)}if(localStats.isFile()&&isLocalPackageArchive(source.absolute_path)){const resolved=await extractLocalPackageArchive(source.absolute_path);return{source,directory:resolved.directory,source_root:path.dirname(resolved.directory),resolved_subpath:path.relative(path.dirname(resolved.directory),resolved.directory).replaceAll(path.sep,"/"),npm_package:resolved.package,npm_version:resolved.version,cleanup:resolved.cleanup}}if(!localStats.isDirectory())throw new PmCliError(`Local extension source must be a directory or npm .tgz/.tar.gz archive: "${source.absolute_path}".`,EXIT_CODE.USAGE);const directory=await resolvePackageExtensionDirectory(source.absolute_path,source.input);return{source,directory,source_root:source.absolute_path}}if(source.kind==="npm"){const resolved=await resolveNpmSourceDirectory(source);return{source,directory:resolved.directory,source_root:path.dirname(resolved.directory),cleanup:resolved.cleanup,resolved_subpath:path.relative(path.dirname(resolved.directory),resolved.directory).replaceAll(path.sep,"/"),npm_package:resolved.package,npm_version:resolved.version}}const cloneDirectory=await fs.mkdtemp(path.join(os.tmpdir(),"pm-extension-source-")),cloneArgs=["clone","--depth","1"];source.ref&&cloneArgs.push("--branch",source.ref),cloneArgs.push(source.repository,cloneDirectory);try{await runGitCommand(cloneArgs);const commit=await runGitCommand(["-C",cloneDirectory,"rev-parse","HEAD"]),resolved=await resolveGithubSourceDirectory(cloneDirectory,source);return{source,directory:resolved.directory,source_root:cloneDirectory,resolved_subpath:resolved.resolved_subpath,commit,cleanup:async()=>{await fs.rm(cloneDirectory,{recursive:!0,force:!0})}}}catch(error){throw await fs.rm(cloneDirectory,{recursive:!0,force:!0}),error}}async function areDirectoriesEquivalent(left,right){if(!await pathExists(left)||!await pathExists(right))return!1;const[leftRealPath,rightRealPath]=await Promise.all([fs.realpath(left),fs.realpath(right)]);return leftRealPath===rightRealPath}const _testOnlyInstallSources={extractLocalPackageArchive,validateLocalPackageArchiveEntry,installNpmPackageRuntimeDependencies,npmPackageNameFromSpec,parsePackedNpmPackage,resolveNpmSourceDirectoryWithRunner,resolveNpmSourceDirectory,resolveNpmPackSpec,findInstalledNpmPackageCandidate,resolvePackageExtensionDirectory,runtimeDependencyInstallSpecs,hasHostedPmCliDependency,removeHostedPmCliDependency,linkHostedPmCliDependency,resolveDirectorySymlinkType,runNpmCommand};export{_testOnlyInstallSources,areDirectoriesEquivalent,buildNpmNotFoundRecovery,findInstalledNpmPackageCandidate,isNpmNotFoundError,isNpmPackNotFoundError,normalizeNpmLocalFileAliasSpec,parseExtensionInstallSource,resolveInstallSource,resolveNpmCommandName,runGitCommand,shouldRunNpmCommandInShell,wrapNpmPackResolutionError};
|
|
5
|
+
`,"utf8")}}function hasHostedPmCliDependency(manifest){for(const dependencyMap of[manifest.dependencies,manifest.optionalDependencies,manifest.peerDependencies])if(typeof dependencyMap=="object"&&dependencyMap!==null&&PM_CLI_PACKAGE_NAME in dependencyMap)return!0;return!1}function removeHostedPmCliDependency(manifest){for(const field of["dependencies","optionalDependencies","peerDependencies"]){const dependencyMap=manifest[field];if(typeof dependencyMap!="object"||dependencyMap===null)continue;const nextMap={...dependencyMap};delete nextMap[PM_CLI_PACKAGE_NAME],Object.keys(nextMap).length===0?delete manifest[field]:manifest[field]=nextMap}}async function linkHostedPmCliDependency(packageRoot){const hostPackageRoot=resolvePmPackageRootFromModule(import.meta.url,["../../.."]),[scope,packageName]=PM_CLI_PACKAGE_NAME.split("/"),scopedDirectory=path.join(packageRoot,"node_modules",scope),linkPath=path.join(scopedDirectory,packageName);await fs.mkdir(scopedDirectory,{recursive:!0}),await fs.rm(linkPath,{recursive:!0,force:!0}),await fs.symlink(hostPackageRoot,linkPath,resolveDirectorySymlinkType(process.platform))}function resolveDirectorySymlinkType(platform){return platform==="win32"?"junction":"dir"}function validateRuntimeDependencySpec(name,version){if(name.startsWith("-"))throw new PmCliError(`Extension runtime dependency name "${name}" is unsafe because npm could interpret it as a command-line option.`,EXIT_CODE.USAGE,{code:"extension_dependency_name_unsafe",required:"Use a valid npm package name that does not begin with a dash.",why:"Extension manifests are untrusted input and dependency names must never become npm options."});if([...version].some(character=>{const codePoint=character.charCodeAt(0);return codePoint<=31||codePoint===127||"&|;()`\"'".includes(character)}))throw new PmCliError(`Extension runtime dependency "${name}" has an unsafe version specifier.`,EXIT_CODE.USAGE,{code:"extension_dependency_version_unsafe",required:"Use an npm version, range, dist-tag, URL, or file specifier without shell metacharacters.",why:"npm.cmd requires a command shell on Windows, so untrusted shell metacharacters cannot be forwarded."});try{npa.resolve(name,version)}catch{throw new PmCliError(`Extension runtime dependency "${name}@${version}" is not a valid npm dependency specifier.`,EXIT_CODE.USAGE,{code:"extension_dependency_spec_invalid",required:"Use a valid npm package name and npm-supported version, range, dist-tag, URL, or file specifier.",why:"Only grammar-validated dependency specs may be written to the isolated runtime install manifest."})}return`${name}@${version}`}function runtimeDependencyInstallSpecs(manifest){const specs=new Map;for(const dependencyMap of[manifest.dependencies,manifest.optionalDependencies,manifest.peerDependencies])if(!(typeof dependencyMap!="object"||dependencyMap===null))for(const[name,version]of Object.entries(dependencyMap)){if(name===PM_CLI_PACKAGE_NAME||typeof version!="string"||version.trim().length===0||specs.has(name))continue;const normalizedVersion=version.trim();specs.set(name,validateRuntimeDependencySpec(name,normalizedVersion))}return[...specs.values()]}async function resolvePackageExtensionDirectory(packageRoot,sourceLabel){const discovered=await collectPackageExtensionDirectories(packageRoot);if(discovered.length===1)return discovered[0];if(discovered.length>1){const choices=discovered.map(entry=>path.relative(packageRoot,entry).replaceAll(path.sep,"/")).sort((left,right)=>left.localeCompare(right));throw new PmCliError(`Package source "${sourceLabel}" contains multiple extension manifests. Provide an explicit extension path. Candidates: ${choices.join(", ")}`,EXIT_CODE.USAGE)}throw new PmCliError(`Unable to locate a pm extension manifest in package source "${sourceLabel}". Package installs currently activate only extension resources, so add package.json pm.extensions or an extensions/ directory. Metadata-only resources like pm.docs/pm.examples are catalog metadata and do not activate commands.`,EXIT_CODE.USAGE)}async function resolveGithubSourceDirectory(cloneDirectory,source){const candidatePaths=[];source.subpath&&(candidatePaths.push(source.subpath),candidatePaths.push(path.posix.join(".agents/pm/extensions",source.subpath)),candidatePaths.push(path.posix.join(".custom/pm-extensions",source.subpath)),candidatePaths.push(path.posix.join(".custom/pm-extension",source.subpath)));for(const candidate of candidatePaths){const absolute=path.resolve(cloneDirectory,candidate);if(isPathWithinDirectory(cloneDirectory,absolute)&&await pathExists(path.join(absolute,"manifest.json")))return{directory:absolute,resolved_subpath:candidate}}if(await pathExists(path.join(cloneDirectory,"manifest.json")))return{directory:cloneDirectory,resolved_subpath:"."};const discoveredDirectory=await resolvePackageExtensionDirectory(cloneDirectory,source.input);return{directory:discoveredDirectory,resolved_subpath:path.relative(cloneDirectory,discoveredDirectory).replaceAll(path.sep,"/")}}function looksLikeBarePackageName(input){const trimmed=input.trim();return trimmed.length===0||trimmed.startsWith(".")||trimmed.startsWith("~")?!1:trimmed.startsWith("@")?trimmed.split("/").length===2:!trimmed.includes("/")&&!trimmed.includes("\\")}async function buildLocalSourceNotFoundError(source){const baseMessage=`Local extension source does not exist: "${source.absolute_path}".`,input=source.input.trim();if(!looksLikeBarePackageName(input))return new PmCliError(baseMessage,EXIT_CODE.NOT_FOUND);let bundledAliases=[];try{const envPackageRoot=process.env.PM_CLI_PACKAGE_ROOT,cacheKey=typeof envPackageRoot=="string"&&envPackageRoot.trim().length>0?path.resolve(envPackageRoot.trim()):"";bundledPackageAliasesCache?.key!==cacheKey&&(bundledPackageAliasesCache={key:cacheKey,aliases:await listBundledPackageAliases()}),bundledAliases=bundledPackageAliasesCache.aliases}catch{}const nextSteps=[`Retry with pm package install npm:${input} if the package is published to npm.`,`Or inspect bundled packages with pm package catalog --project --json before installing by alias. Known aliases (blank means none found): ${bundledAliases.join(", ")}`];return new PmCliError(`${baseMessage} "${input}" did not match a local directory, bundled package alias, or bundled package name; if you meant an npm package, install it as "npm:${input}".`,EXIT_CODE.NOT_FOUND,{code:"local_source_not_found_bare_name",required:`Use "npm:${input}" for npm registry packages, a bundled catalog alias, or an existing local directory path.`,why:"Bare names resolve as local paths only after bundled aliases, so unmatched names need an explicit npm: source.",examples:[`pm package install npm:${input}`,"pm package catalog --project --json"],nextSteps,recovery:{attempted_command:`pm install ${input}`,normalized_args:["install",input],next_best_command:`pm package install npm:${input}`}})}async function resolveInstallSource(source){if(source.kind==="local"){let localStats;try{localStats=await fs.stat(source.absolute_path)}catch{throw await buildLocalSourceNotFoundError(source)}if(localStats.isFile()&&isLocalPackageArchive(source.absolute_path)){const resolved=await extractLocalPackageArchive(source.absolute_path);return{source,directory:resolved.directory,source_root:path.dirname(resolved.directory),resolved_subpath:path.relative(path.dirname(resolved.directory),resolved.directory).replaceAll(path.sep,"/"),npm_package:resolved.package,npm_version:resolved.version,cleanup:resolved.cleanup}}if(!localStats.isDirectory())throw new PmCliError(`Local extension source must be a directory or npm .tgz/.tar.gz archive: "${source.absolute_path}".`,EXIT_CODE.USAGE);const directory=await resolvePackageExtensionDirectory(source.absolute_path,source.input);return{source,directory,source_root:source.absolute_path}}if(source.kind==="npm"){const resolved=await resolveNpmSourceDirectory(source);return{source,directory:resolved.directory,source_root:path.dirname(resolved.directory),cleanup:resolved.cleanup,resolved_subpath:path.relative(path.dirname(resolved.directory),resolved.directory).replaceAll(path.sep,"/"),npm_package:resolved.package,npm_version:resolved.version}}const cloneDirectory=await fs.mkdtemp(path.join(os.tmpdir(),"pm-extension-source-")),cloneArgs=["clone","--depth","1"];source.ref&&cloneArgs.push("--branch",source.ref),cloneArgs.push(source.repository,cloneDirectory);try{await runGitCommand(cloneArgs);const commit=await runGitCommand(["-C",cloneDirectory,"rev-parse","HEAD"]),resolved=await resolveGithubSourceDirectory(cloneDirectory,source);return{source,directory:resolved.directory,source_root:cloneDirectory,resolved_subpath:resolved.resolved_subpath,commit,cleanup:async()=>{await fs.rm(cloneDirectory,{recursive:!0,force:!0})}}}catch(error){throw await fs.rm(cloneDirectory,{recursive:!0,force:!0}),error}}async function areDirectoriesEquivalent(left,right){if(!await pathExists(left)||!await pathExists(right))return!1;const[leftRealPath,rightRealPath]=await Promise.all([fs.realpath(left),fs.realpath(right)]);return leftRealPath===rightRealPath}const _testOnlyInstallSources={extractLocalPackageArchive,validateLocalPackageArchiveEntry,installNpmPackageRuntimeDependencies,npmPackageNameFromSpec,parsePackedNpmPackage,resolveNpmSourceDirectoryWithRunner,resolveNpmSourceDirectory,resolveNpmPackSpec,findInstalledNpmPackageCandidate,resolvePackageExtensionDirectory,runtimeDependencyInstallSpecs,hasHostedPmCliDependency,removeHostedPmCliDependency,linkHostedPmCliDependency,resolveDirectorySymlinkType,runNpmCommand};export{_testOnlyInstallSources,areDirectoriesEquivalent,buildNpmNotFoundRecovery,findInstalledNpmPackageCandidate,isNpmNotFoundError,isNpmPackNotFoundError,normalizeNpmLocalFileAliasSpec,parseExtensionInstallSource,resolveInstallSource,resolveNpmCommandName,runGitCommand,shouldRunNpmCommandInShell,wrapNpmPackResolutionError};
|
|
6
6
|
//# sourceMappingURL=install-sources.js.map
|
|
@@ -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]="9cf5a9e7-4a66-5e72-80a2-f8a9b5b6e412")}catch{}})();import fs from"node:fs/promises";import path from"node:path";import{pathExists}from"../../core/fs/fs-utils.js";import{isPathWithinDirectory}from"../../core/fs/path-utils.js";import{EXIT_CODE}from"../../core/shared/constants.js";import{PmCliError}from"../../core/shared/errors.js";import{isCanonicalPathWithinDirectory,parseExtensionManifestDocument}from"../../core/extensions/loader.js";function normalizeStringList(values){return[...new Set(values.map(value=>value.trim()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeExtensionNameForMatch(value){return value.trim().toLowerCase()}function normalizeManagedDirectoryName(name){const normalized=name.trim().toLowerCase().replace(/[^a-z0-9._-]+/g,"-");let start=0;for(;normalized[start]==="-";)start+=1;let end=normalized.length;for(;end>start&&normalized[end-1]==="-";)end-=1;const directoryName=normalized.slice(start,end);if(directoryName.length===0)throw new PmCliError("Extension manifest name must resolve to a non-empty directory name.",EXIT_CODE.USAGE);if(directoryName==="."||directoryName==="..")throw new PmCliError('Extension manifest name must not resolve to "." or "..".',EXIT_CODE.USAGE);return directoryName}function parseExtensionManifest(raw){return parseExtensionManifestDocument(raw)}async function readGithubSourcePackageMetadata(sourceRoot){try{const packageJson=JSON.parse(await fs.readFile(path.join(sourceRoot,"package.json"),"utf8")),packageName=typeof packageJson.name=="string"&&/^(?:@[a-z0-9._~-]+\/)?[a-z0-9._~-]+$/iu.test(packageJson.name)?packageJson.name:void 0;return{...packageName?{package_name:packageName}:{},has_build_script:["build","prepare","prepack"].some(key=>typeof packageJson.scripts?.[key]=="string")}}catch{return{has_build_script:!1}}}async function missingExtensionEntryError(manifest,entryPath,context){if(context.source_kind!=="github"||typeof context.source_root!="string")return new PmCliError(`Extension entry file is missing at "${entryPath}".`,EXIT_CODE.USAGE);const packageMetadata=await readGithubSourcePackageMetadata(context.source_root),npmCommand=packageMetadata.package_name?`pm package install npm:${packageMetadata.package_name}`:void 0,source=context.source_input??context.source_root;return new PmCliError(`Extension entry "${manifest.entry}" is absent from GitHub source "${source}". pm package install copies GitHub repositories without running package scripts${packageMetadata.has_build_script?", and this package declares a build or publish script":""}. ${npmCommand?`Try "${npmCommand}" if the package is published, or install a locally built directory.`:"Build the source locally and install that directory, or use its published npm: package."}`,EXIT_CODE.USAGE,{code:"github_source_entry_unbuilt",required:"Use a GitHub tree with committed runtime output, a published npm artifact, or a locally built source directory.",why:"GitHub installation is a source copy and never executes untrusted package build scripts.",examples:npmCommand?[npmCommand,`pm package install ${context.source_root}`]:[`pm package install ${context.source_root}`],nextSteps:npmCommand?[`Retry with ${npmCommand}.`,"Or build the repository locally, then install its directory."]:["Build the repository locally, then install its directory.","If it is published, retry with pm package install npm:<package-name>."],recovery:{attempted_command:`pm install ${source}`,normalized_args:["install",source],...npmCommand?{next_best_command:npmCommand}:{}}})}async function validateExtensionDirectory(directory,context={}){const manifestPath=path.join(directory,"manifest.json");if(!await pathExists(manifestPath))throw new PmCliError(`Extension manifest is missing at "${manifestPath}".`,EXIT_CODE.USAGE);let parsedManifest;try{parsedManifest=JSON.parse(await fs.readFile(manifestPath,"utf8"))}catch(error){throw new PmCliError(`Failed to parse extension manifest at "${manifestPath}": ${formatManifestReadError(error)}`,EXIT_CODE.USAGE)}const manifest=parseExtensionManifest(parsedManifest);if(!manifest)throw new PmCliError(`Extension manifest at "${manifestPath}" is invalid.`,EXIT_CODE.USAGE);const entryPath=path.resolve(directory,manifest.entry);if(!isPathWithinDirectory(directory,entryPath))throw new PmCliError(`Extension entry "${manifest.entry}" resolves outside extension directory "${directory}".`,EXIT_CODE.USAGE);if(!await pathExists(entryPath))throw await missingExtensionEntryError(manifest,entryPath,context);if(!await isCanonicalPathWithinDirectory(directory,entryPath))throw new PmCliError(`Extension entry "${manifest.entry}" resolves outside extension directory after symlink resolution.`,EXIT_CODE.USAGE);return{directory,manifest_path:manifestPath,entry_path:entryPath,manifest}}function formatManifestReadError(error){return error instanceof Error?error.message:String(error)}const _testOnlyExtensionShared={formatManifestReadError};export{_testOnlyExtensionShared,isCanonicalPathWithinDirectory,normalizeExtensionNameForMatch,normalizeManagedDirectoryName,normalizeStringList,parseExtensionManifest,validateExtensionDirectory};
|
|
2
2
|
//# sourceMappingURL=shared.js.map
|