@unbrained/pm-cli 2026.10.5 → 2026.10.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +26 -1
  3. package/dist/cli/register-setup.js +1 -1
  4. package/dist/cli/runtime/projection-retry.js +1 -1
  5. package/dist/cli-bundle/bundle-manifest.json +158 -158
  6. package/dist/cli-bundle/chunks/{chunk-Z66DWDAU.js → chunk-25EW53VO.js} +39 -38
  7. package/dist/cli-bundle/chunks/{chunk-YVBRASXO.js → chunk-3CCVTV6Q.js} +2 -2
  8. package/dist/cli-bundle/chunks/{chunk-5MNOWZPN.js → chunk-3REXBTST.js} +2 -2
  9. package/dist/cli-bundle/chunks/chunk-4WB55TBC.js +80 -0
  10. package/dist/cli-bundle/chunks/{chunk-OOLYASYJ.js → chunk-6STTPXOC.js} +2 -2
  11. package/dist/cli-bundle/chunks/{chunk-AJ7H6XUF.js → chunk-ATB4ZZBQ.js} +2 -2
  12. package/dist/cli-bundle/chunks/{chunk-N4YGSG6F.js → chunk-D4G43LBV.js} +38 -38
  13. package/dist/cli-bundle/chunks/{chunk-HRJ6G6ZG.js → chunk-K6D6DMRT.js} +28 -28
  14. package/dist/cli-bundle/chunks/chunk-KIRHWPZB.js +2 -0
  15. package/dist/cli-bundle/chunks/chunk-O67BH435.js +6 -0
  16. package/dist/cli-bundle/chunks/{chunk-3CYOBJUK.js → chunk-RJHLD64E.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-WFZ4UEOB.js → chunk-TUKO5NF7.js} +2 -2
  18. package/dist/cli-bundle/chunks/{chunk-VZ63DEVJ.js → chunk-XJD47LUH.js} +2 -2
  19. package/dist/cli-bundle/chunks/{register-list-query-75QXHIFH.js → register-list-query-53WYLNZT.js} +2 -2
  20. package/dist/cli-bundle/chunks/{register-mutation-YS54SCHG.js → register-mutation-34XXUBVI.js} +2 -2
  21. package/dist/cli-bundle/chunks/{register-operations-6KHZQSYJ.js → register-operations-WANO6EIM.js} +2 -2
  22. package/dist/cli-bundle/chunks/register-setup-WT37UPBQ.js +2 -0
  23. package/dist/cli-bundle/focused-chunks/{chunk-GITOYRUW.js → chunk-6KFKQD2D.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/{chunk-UDYRVBOZ.js → chunk-FOHRPFIT.js} +2 -2
  25. package/dist/cli-bundle/focused-chunks/{chunk-DDRN42PB.js → chunk-GRQXL5G5.js} +2 -2
  26. package/dist/cli-bundle/focused-chunks/{chunk-ABV67XCC.js → chunk-JZ4WGUVH.js} +2 -2
  27. package/dist/cli-bundle/focused-chunks/{chunk-B5RSLVE6.js → chunk-NM3PM6O6.js} +2 -2
  28. package/dist/cli-bundle/focused-chunks/chunk-OT7HK7SG.js +2 -0
  29. package/dist/cli-bundle/focused-chunks/{chunk-2CVX3KR3.js → chunk-PCLU34KB.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-5C3IDDW7.js → chunk-QQIE4L42.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/chunk-RPUNVKXK.js +2 -0
  32. package/dist/cli-bundle/focused-chunks/{chunk-LE4JUCRR.js → chunk-RXSVJPZ7.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-SPN5QTZ3.js +30 -0
  34. package/dist/cli-bundle/focused-chunks/{chunk-CLDPTMQY.js → chunk-SUZJNPGB.js} +2 -2
  35. package/dist/cli-bundle/focused-chunks/{chunk-YMU42COG.js → chunk-W4BG5HHS.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/{chunk-C224METM.js → chunk-Y5HXFDTZ.js} +2 -2
  37. package/dist/cli-bundle/focused-chunks/{chunk-ECBOPEJE.js → chunk-ZK5SOOPC.js} +61 -61
  38. package/dist/cli-bundle/focused-chunks/chunk-ZQK2XUSS.js +12 -0
  39. package/dist/cli-bundle/main.js +21 -21
  40. package/dist/cli-bundle/sdk-authoring.js +1 -1
  41. package/dist/cli-bundle/sdk-contracts.js +1 -1
  42. package/dist/cli-bundle/sdk-core.js +31 -30
  43. package/dist/cli-bundle/sdk-governance.js +1 -1
  44. package/dist/cli-bundle/sdk-graph.js +1 -1
  45. package/dist/cli-bundle/sdk-merge.js +42 -42
  46. package/dist/cli-bundle/sdk-query.js +1 -1
  47. package/dist/cli-bundle/sdk-runtime.js +1 -1
  48. package/dist/cli-bundle/sdk-testing.js +1 -1
  49. package/dist/cli-bundle/sdk.js +2 -2
  50. package/dist/core/extensions/extension-types.d.ts +2 -0
  51. package/dist/core/extensions/extension-types.js +1 -1
  52. package/dist/sdk/cli-bootstrap.d.ts +5 -1
  53. package/dist/sdk/cli-bootstrap.js +1 -1
  54. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  55. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
  56. package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
  57. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  58. package/dist/sdk/cli-contracts/tool-schema.js +1 -1
  59. package/dist/sdk/extension/managed-state.d.ts +2 -0
  60. package/dist/sdk/extension/managed-state.js +1 -1
  61. package/dist/sdk/extension/managed-update-status.d.ts +3 -0
  62. package/dist/sdk/extension/managed-update-status.js +2 -0
  63. package/dist/sdk/extension/source-resolution.d.ts +2 -6
  64. package/dist/sdk/extension/source-resolution.js +1 -1
  65. package/dist/sdk/extension/update-check.d.ts +10 -0
  66. package/dist/sdk/extension/update-check.js +1 -1
  67. package/dist/sdk/extension-command-context.js +2 -1
  68. package/dist/sdk/extension.d.ts +4 -0
  69. package/dist/sdk/extension.js +1 -1
  70. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  71. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
  72. package/dist/sdk/public-surface.json +1 -1
  73. package/dist/sdk/query/get.js +1 -1
  74. package/dist/sdk/read-output-contracts.js +1 -1
  75. package/dist/sdk/runtime-input.js +1 -1
  76. package/dist/sdk/test/execution.d.ts +2 -1
  77. package/dist/sdk/test/execution.js +3 -3
  78. package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +36 -0
  79. package/docs/GET_READ_EVIDENCE.md +17 -1
  80. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +23 -0
  81. package/docs/PR_REVIEW_LOOP.md +21 -4
  82. package/docs/README.md +1 -0
  83. package/docs/RELEASING.md +18 -0
  84. package/docs/SDK_CONFIGURATION_SAFETY.md +123 -0
  85. package/docs/generated/FLAG_LEXICON_BUDGETS.md +3 -3
  86. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
  87. package/marketplace.json +2 -2
  88. package/package.json +3 -3
  89. package/packages/pm-beads/package.json +1 -1
  90. package/packages/pm-calendar/package.json +1 -1
  91. package/packages/pm-command-kit/package.json +1 -1
  92. package/packages/pm-digital-twin/package.json +1 -1
  93. package/packages/pm-governance-audit/package.json +1 -1
  94. package/packages/pm-guide-shell/package.json +1 -1
  95. package/packages/pm-kanban/package.json +1 -1
  96. package/packages/pm-lifecycle-hooks/package.json +1 -1
  97. package/packages/pm-linked-test-adapters/package.json +1 -1
  98. package/packages/pm-search-advanced/package.json +1 -1
  99. package/packages/pm-templates/package.json +1 -1
  100. package/packages/pm-todos/package.json +1 -1
  101. package/packages/pm-vcs/package.json +1 -1
  102. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  103. package/plugins/pm-claude/package.json +2 -2
  104. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  105. package/plugins/pm-codex/package.json +2 -2
  106. package/plugins/pm-codex/plugin.json +1 -1
  107. package/dist/cli-bundle/chunks/chunk-D332RXZ7.js +0 -80
  108. package/dist/cli-bundle/chunks/chunk-KRVI56QE.js +0 -6
  109. package/dist/cli-bundle/chunks/chunk-TGMONGWX.js +0 -2
  110. package/dist/cli-bundle/chunks/register-setup-RTATEN2M.js +0 -2
  111. package/dist/cli-bundle/focused-chunks/chunk-DOVTUKJQ.js +0 -2
  112. package/dist/cli-bundle/focused-chunks/chunk-GUIF3WVC.js +0 -30
  113. package/dist/cli-bundle/focused-chunks/chunk-RHIH6XIW.js +0 -12
  114. package/dist/cli-bundle/focused-chunks/chunk-XV5RV4ZT.js +0 -2
@@ -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]="f34e0f7f-952c-5673-82b2-6bf87c10c7be")}catch{}})();import fs from"node:fs/promises";import path from"node:path";import{activateExtensions,createSerialQueue,loadExtensions,nextExtensionReloadToken}from"../core/extensions/index.js";import{describeExtensionActivation}from"../core/extensions/activation-summary.js";import{createExtensionContributionInventory}from"../core/extensions/contribution-inventory.js";import{resolveExtensionRoots}from"../core/extensions/loader.js";import{pathExists}from"../core/fs/fs-utils.js";import{resolvePmPackageRootFromModule}from"../core/packages/root.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{levenshteinDistanceWithinLimit}from"../core/shared/levenshtein.js";import{nowIso}from"../core/shared/time.js";import{resolveGlobalPmRoot,resolvePmRoot}from"../core/store/paths.js";import{readSettings,writeSettings}from"../core/store/settings.js";import{quoteCommandArg,renderPmCommand}from"./command-line.js";import{createUnknownSubcommandError}from"./agent/subcommand-recovery.js";import{ensureTypeFolderScaffold}from"./schema.js";import{normalizeStringList,normalizeExtensionNameForMatch,normalizeManagedDirectoryName,parseExtensionManifest,validateExtensionDirectory}from"./extension/shared.js";import{sortManagedEntries,managedExtensionSourcesEquivalent,readManagedExtensionState,writeManagedExtensionState,upsertManagedEntry,persistManagedContributionInventory,resolveManagedExtensionStatePath}from"./extension/managed-state.js";import{parseExtensionInstallSource,resolveInstallSource,areDirectoriesEquivalent}from"./extension/install-sources.js";import{resolveBundledExtensionAliasSource,isBundledPackageInstallAllTarget,listBundledPackageAliases,resolveBundledAliasManifestName,buildBundledPackageCatalog}from"./extension/bundled-catalog.js";import{scaffoldExtensionProject}from"./extension/scaffold.js";import{buildExtensionDescribeResult}from"./extension/describe.js";import{applyDoctorRuntimeActivationState,classifyDoctorLoadFailureWarnings,classifyDoctorActivationFailureWarnings,classifyUnusedCapabilityWarnings,buildExtensionTriageSummary,parseDoctorDetailMode,collectUnknownCapabilityGuidance,buildCapabilityContractMetadata,buildDoctorConsistencySummary,summarizeExtensionFailures}from"./extension/doctor.js";import{copyExtensionDirectoryForInstall,copyExtensionDirectoryWithoutSelfNesting,ensureExtensionModuleTypeMarker,ensureInstalledExtensionSdkLink,isErrnoCode,isRetriableExtensionInstallCopyError,resolveCanonicalExtensionInstallDestination,withExtensionInstallLock}from"./extension/install-runtime.js";import{mapWithFixedConcurrency}from"./extension/concurrency.js";import{summarizeRuntimeCommandPathsForExtension}from"./extension/runtime-summary.js";import{collectGlobalOutputOverrideDoctorWarnings}from"./extension/output-ownership.js";import{collectMcpCustomFieldCollisionDoctorWarnings}from"./extension/custom-field-collisions.js";import{checkGithubUpdate}from"./extension/update-check.js";import{runExtensionMigrateAction}from"./extension/migrations.js";import{buildBundledInstallReceipt}from"./extension/install-receipts.js";import{buildExtensionInstallPlan}from"./extension/install-plan.js";import{inspectExtensionAuthorManifestAtPmRoot}from"./extension/author-manifest.js";import{resolveExtensionInstallSourceIdentity}from"./extension/source-resolution.js";import{captureExtensionInstallSnapshot,readOptionalMetadataFile,restoreExtensionInstallSnapshot}from"./extension/install-snapshot.js";const GITHUB_UPDATE_CHECK_CONCURRENCY=4,LIFECYCLE_ACTION_TARGETS=[["install","install","--install"],["uninstall","uninstall","--uninstall"],["explore","explore","--explore"],["list","explore","--explore"],["manage","manage","--manage"],["describe","describe","--describe"],["reload","reload","--reload"],["doctor","doctor","--doctor"],["catalog","catalog","--catalog"],["init","init","--init"],["scaffold","init","--scaffold"],["adopt","adopt","--adopt"],["adopt-all","adopt-all","--adopt-all"],["activate","activate","--activate"],["deactivate","deactivate","--deactivate"],["migrate","migrate","--migrate"]],LIFECYCLE_ACTION_FLAG_HINT=LIFECYCLE_ACTION_TARGETS.map(([,,flag])=>flag).filter((flag,index,flags)=>flags.indexOf(flag)===index).join(", "),LIFECYCLE_ACTION_FLAGS={install:"--install",uninstall:"--uninstall",explore:"--explore",manage:"--manage",describe:"--describe",reload:"--reload",doctor:"--doctor",catalog:"--catalog",adopt:"--adopt","adopt-all":"--adopt-all",activate:"--activate",deactivate:"--deactivate",migrate:"--migrate",init:"--init"},NATIVE_OUTPUT_MARKER="__pm_native_output",EXTENSION_POLICY_ROOT_LIST_FIELDS=["trusted_extensions","allowed_extensions","blocked_extensions","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"],EXTENSION_POLICY_OVERRIDE_LIST_FIELDS=["allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"],EXTENSION_POLICY_OVERRIDE_BOOLEAN_FIELDS=["disabled","require_trusted","require_provenance"],DEFAULT_EXTENSION_POLICY_DETAILS={mode:"off",trust_mode:"off",require_provenance:!1,trusted_extensions:[],default_sandbox_profile:"none",allowed_extensions:[],blocked_extensions:[],allowed_capabilities:[],blocked_capabilities:[],allowed_surfaces:[],blocked_surfaces:[],allowed_commands:[],blocked_commands:[],allowed_actions:[],blocked_actions:[],allowed_services:[],blocked_services:[],extension_overrides:[]},normalizePolicyRootLists=policy=>{const safePolicy=policy??DEFAULT_EXTENSION_POLICY_DETAILS,lists={};for(const field of EXTENSION_POLICY_ROOT_LIST_FIELDS)lists[field]=normalizeStringList(safePolicy[field]??[]);return lists},appendNonEmptyPolicyLists=(target,lists)=>{for(const field of EXTENSION_POLICY_OVERRIDE_LIST_FIELDS)lists[field].length>0&&(target[field]=lists[field]);return target},appendEnabledPolicyScalars=(target,override)=>{for(const field of EXTENSION_POLICY_OVERRIDE_BOOLEAN_FIELDS)override[field]===!0&&(target[field]=!0);return override.sandbox_profile&&(target.sandbox_profile=override.sandbox_profile),target},normalizePolicyOverrideLists=override=>{const lists={};for(const field of EXTENSION_POLICY_OVERRIDE_LIST_FIELDS)lists[field]=normalizeStringList(override[field]??[]);return lists},buildExtensionPolicyOverrideDetails=override=>{const name=typeof override.name=="string"?override.name.trim():"";return name.length===0?null:appendNonEmptyPolicyLists(appendEnabledPolicyScalars({name},override),normalizePolicyOverrideLists(override))},normalizeExtensionPolicyOverrides=overrides=>(overrides??[]).map(override=>buildExtensionPolicyOverrideDetails(override)).filter(override=>override!==null).sort((left,right)=>left.name.localeCompare(right.name)),buildExtensionPolicyDetails=policy=>{const safePolicy=Object.assign({},DEFAULT_EXTENSION_POLICY_DETAILS,policy??{}),rootLists=normalizePolicyRootLists(policy),overrides=normalizeExtensionPolicyOverrides(safePolicy.extension_overrides);return{mode:safePolicy.mode,trust_mode:safePolicy.trust_mode,require_provenance:safePolicy.require_provenance===!0,trusted_extensions:rootLists.trusted_extensions,default_sandbox_profile:safePolicy.default_sandbox_profile,allowed_extensions:rootLists.allowed_extensions,blocked_extensions:rootLists.blocked_extensions,allowed_capabilities:rootLists.allowed_capabilities,blocked_capabilities:rootLists.blocked_capabilities,allowed_surfaces:rootLists.allowed_surfaces,blocked_surfaces:rootLists.blocked_surfaces,allowed_commands:rootLists.allowed_commands,blocked_commands:rootLists.blocked_commands,allowed_actions:rootLists.allowed_actions,blocked_actions:rootLists.blocked_actions,allowed_services:rootLists.allowed_services,blocked_services:rootLists.blocked_services,extension_overrides:overrides}},resolveInstalledExtensionCandidate=async(installed,extensionTarget)=>{const lookupValues=[extensionTarget],bundledAliasManifestName=await resolveBundledAliasManifestName(extensionTarget);bundledAliasManifestName&&lookupValues.push(bundledAliasManifestName);const normalizedLookups=[...new Set(lookupValues.map(value=>normalizeExtensionNameForMatch(value)).filter(value=>value.length>0))];for(const lookup of normalizedLookups){const byName=installed.find(entry=>normalizeExtensionNameForMatch(entry.name)===lookup);if(byName)return byName;const byDirectory=installed.find(entry=>normalizeExtensionNameForMatch(entry.directory)===lookup);if(byDirectory)return byDirectory}},isExtensionEnabled=(settings,name)=>{const normalizedName=name.trim(),enabled=new Set(normalizeStringList(settings.extensions.enabled));return new Set(normalizeStringList(settings.extensions.disabled)).has(normalizedName)?!1:enabled.size===0?!0:enabled.has(normalizedName)},ensureActivated=(settings,name)=>{const normalizedName=name.trim(),enabled=new Set(normalizeStringList(settings.extensions.enabled)),disabled=new Set(normalizeStringList(settings.extensions.disabled)),previousEnabled=[...enabled],previousDisabled=[...disabled];return disabled.delete(normalizedName),enabled.size>0&&enabled.add(normalizedName),settings.extensions.enabled=[...enabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.disabled=[...disabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.enabled.join("\0")!==previousEnabled.join("\0")||settings.extensions.disabled.join("\0")!==previousDisabled.join("\0")},ensureDeactivated=(settings,name)=>{const normalizedName=name.trim(),enabled=new Set(normalizeStringList(settings.extensions.enabled)),disabled=new Set(normalizeStringList(settings.extensions.disabled)),previousEnabled=[...enabled],previousDisabled=[...disabled];return enabled.delete(normalizedName),disabled.add(normalizedName),settings.extensions.enabled=[...enabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.disabled=[...disabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.enabled.join("\0")!==previousEnabled.join("\0")||settings.extensions.disabled.join("\0")!==previousDisabled.join("\0")},clearExtensionState=(settings,name)=>{const normalizedName=name.trim(),enabled=new Set(normalizeStringList(settings.extensions.enabled)),disabled=new Set(normalizeStringList(settings.extensions.disabled)),previousEnabled=[...enabled],previousDisabled=[...disabled];return enabled.delete(normalizedName),disabled.delete(normalizedName),settings.extensions.enabled=[...enabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.disabled=[...disabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.enabled.join("\0")!==previousEnabled.join("\0")||settings.extensions.disabled.join("\0")!==previousDisabled.join("\0")},suggestLifecycleActionTarget=target=>{const normalizedTarget=target.trim().toLowerCase(),maxDistance=Math.min(2,Math.max(1,Math.ceil(normalizedTarget.length/4))),nearest=LIFECYCLE_ACTION_TARGETS.map(([candidate,action,flag])=>({action,flag,distance:levenshteinDistanceWithinLimit(normalizedTarget,candidate,maxDistance)})).filter(entry=>entry.distance!==null).sort((left,right)=>left.distance-right.distance)[0];return nearest?{action:nearest.action,flag:nearest.flag}:null},buildUnknownLifecycleActionError=(target,options)=>{const noun=options.vocabulary==="package"?"package":"extension",suggestion=suggestLifecycleActionTarget(target);if(!suggestion)return new PmCliError(`One action flag is required. Use one of: ${LIFECYCLE_ACTION_FLAG_HINT}. Bare \`pm package\` and \`pm extension\` default to --explore.`,EXIT_CODE.USAGE);const command=`pm ${noun} ${suggestion.flag}`;return createUnknownSubcommandError({command_path:noun,display_name:`${noun} lifecycle`,token_kind:"action",token:target,allowed:Object.keys(IMPLICIT_EXTENSION_ACTIONS),retry_command:command,message_suffix:`. Did you mean "${suggestion.flag}"?`,fallback_candidates:[{source:"lifecycle_action",command,reason:`nearest lifecycle action for "${target}"`}]})},EXTENSION_ACTION_FLAG_SELECTORS=[["install","install"],["uninstall","uninstall"],["explore","explore"],["manage","manage"],["describe","describe"],["reload","reload"],["doctor","doctor"],["catalog","catalog"],["init","init"],["scaffold","init"],["adopt","adopt"],["adoptAll","adopt-all"],["activate","activate"],["deactivate","deactivate"],["migrate","migrate"]],IMPLICIT_EXTENSION_ACTIONS={doctor:"doctor",reload:"reload",catalog:"catalog",init:"init",scaffold:"init",explore:"explore",manage:"manage",migrate:"migrate",list:"explore","":"explore"},resolveImplicitActionFromTarget=normalizedTarget=>IMPLICIT_EXTENSION_ACTIONS[normalizedTarget]??null,resolveAction=(target,options)=>{const selected=[...new Set(EXTENSION_ACTION_FLAG_SELECTORS.filter(([flag])=>options[flag]===!0).map(([,mappedAction])=>mappedAction))];if(selected.length===0){if(target===void 0)return"explore";const implicitAction=resolveImplicitActionFromTarget(target.trim().toLowerCase());if(implicitAction)return implicitAction;throw buildUnknownLifecycleActionError(target,options)}if(selected.length>1)throw new PmCliError("Extension action flags are mutually exclusive.",EXIT_CODE.USAGE);return selected[0]},resolveScope=options=>{const projectLike=options.project===!0||options.local===!0,global2=options.global===!0;if(projectLike&&global2)throw new PmCliError('Options "--project/--local" and "--global" are mutually exclusive.',EXIT_CODE.USAGE);return global2?"global":"project"},EXTENSION_UPDATE_CHECK_RESOLVERS=[managedEntry=>managedEntry?null:{status:"skipped_unmanaged",reason:"extension_not_managed"},managedEntry=>managedEntry&&managedEntry.source.kind!=="github"?{status:"skipped_non_github",reason:`managed_source_kind_${managedEntry.source.kind}`}:null,managedEntry=>{const updateError=typeof managedEntry?.update_error=="string"?managedEntry.update_error.trim():"";return updateError.length>0?{status:"failed",reason:updateError}:null},managedEntry=>{const entry=managedEntry;return(typeof entry.last_update_check_at=="string"?entry.last_update_check_at.trim():"").length===0?null:{status:"checked",reason:{true:"update_available",false:"up_to_date"}[String(entry.update_available)]??"checked_without_commit_baseline"}}],resolveUpdateCheckResolution=managedEntry=>{for(const resolve of EXTENSION_UPDATE_CHECK_RESOLVERS){const resolution=resolve(managedEntry);if(resolution)return resolution}return{status:"not_checked",reason:"no_update_check_recorded"}},buildInstalledExtensionSummary=(identity,scope,managedEntry,updateCheck)=>{const managed=managedEntry??{};return{name:identity.name,directory:identity.directory,version:identity.version,entry:identity.entry,scope,active:identity.enabled,enabled:identity.enabled,runtime_active:null,activation_status:"unknown",contributions:managed.contributions,managed:!!managedEntry,source:managed.source,update_available:managed.update_available,last_update_check_at:managed.last_update_check_at,last_update_remote_commit:managed.last_update_remote_commit,update_error:managed.update_error,update_check_status:updateCheck.status,update_check_reason:updateCheck.reason}},buildMissingManifestInspection=(directoryName,scope,settings,managedEntry)=>{const managed=Object.assign({name:directoryName,manifest_version:"unknown",manifest_entry:"unknown"},managedEntry),enabled=managedEntry?isExtensionEnabled(settings,managedEntry.name):!1;return{warning:`extension_manifest_missing:${scope}:${directoryName}`,summary:buildInstalledExtensionSummary({name:managed.name,directory:directoryName,version:managed.manifest_version,entry:managed.manifest_entry,enabled},scope,managedEntry,resolveUpdateCheckResolution(managedEntry))}},inspectInstalledExtensionDirectory=async(extensionsRoot,directoryName,scope,settings,managedByName,managedByDirectory)=>{const extensionDirectory=path.join(extensionsRoot,directoryName),manifestPath=path.join(extensionDirectory,"manifest.json"),managedDirectoryEntry=managedByDirectory.get(normalizeExtensionNameForMatch(directoryName));if(!await pathExists(manifestPath))return buildMissingManifestInspection(directoryName,scope,settings,managedDirectoryEntry);const invalidJson=Symbol("invalid-extension-manifest-json"),rawManifest=await fs.readFile(manifestPath,"utf8").then(contents=>JSON.parse(contents)).catch(()=>invalidJson);if(rawManifest===invalidJson)return{warning:`extension_manifest_invalid_json:${scope}:${directoryName}`};const manifest=parseExtensionManifest(rawManifest);if(!manifest)return{warning:`extension_manifest_invalid:${scope}:${directoryName}`};const managedEntry=managedByName.get(normalizeExtensionNameForMatch(manifest.name))??managedByDirectory.get(normalizeExtensionNameForMatch(directoryName));return{summary:buildInstalledExtensionSummary({name:manifest.name,directory:directoryName,version:manifest.version,entry:manifest.entry,enabled:isExtensionEnabled(settings,manifest.name)},scope,managedEntry,resolveUpdateCheckResolution(managedEntry))}},listInstalledExtensions=async(extensionsRoot,scope,settings,state)=>{if(!await pathExists(extensionsRoot))return{extensions:[],warnings:[]};const directories=(await fs.readdir(extensionsRoot,{withFileTypes:!0})).filter(entry=>entry.isDirectory()).map(entry=>entry.name).sort((left,right)=>left.localeCompare(right)),managedByName=new Map(state.entries.map(managedEntry=>[normalizeExtensionNameForMatch(managedEntry.name),managedEntry])),managedByDirectory=new Map(state.entries.map(managedEntry=>[normalizeExtensionNameForMatch(managedEntry.directory),managedEntry])),warnings=[],summaries=[];for(const directoryName of directories){const inspected=await inspectInstalledExtensionDirectory(extensionsRoot,directoryName,scope,settings,managedByName,managedByDirectory);inspected.warning&&warnings.push(inspected.warning),inspected.summary&&summaries.push(inspected.summary)}return{extensions:summaries.sort((left,right)=>left.name.localeCompare(right.name)),warnings:warnings.sort((left,right)=>left.localeCompare(right))}},extensionRuntimeProbeQueue=createSerialQueue(),resolveCommandDiscoveryPackageName=(extensionName,source)=>[source.package,source.kind==="builtin"?source.name:void 0].find(candidate=>candidate?.trim())?.trim()??extensionName,buildInstallCommandDiscovery=(extensionName,source,commandSummary,activationFailure)=>{const helpCommands=commandSummary.command_paths.map(commandPath=>`pm ${commandPath} --help`),sdkDependencyMissing=activationFailure?.error.toLowerCase().includes("@unbrained/pm-cli")===!0,nextSteps=commandSummary.command_paths.length>0?[...helpCommands]:["Run pm package doctor --project --detail deep if expected package commands are missing."];return sdkDependencyMissing&&nextSteps.unshift("Install @unbrained/pm-cli in the target workspace so declarative package runtime imports resolve, then reinstall the package."),{package_name:resolveCommandDiscoveryPackageName(extensionName,source),extension_name:extensionName,command_paths:commandSummary.command_paths,action_paths:commandSummary.action_paths,help_commands:helpCommands,next_steps:nextSteps,...sdkDependencyMissing?{sdk_dependency_status:"missing"}:{}}},summarizeActivationFailureForDiagnostics=failure=>{const trace=failure.trace,summary={layer:failure.layer,name:failure.name,entry_path:failure.entry_path,error:failure.error};return trace&&(summary.trace=Object.fromEntries(Object.entries(trace).filter(([,value])=>value!==void 0)),trace.missing_capability&&(summary.missing_capability=trace.missing_capability),trace.hint&&(summary.hint=trace.hint)),summary},collectActivationFailureDiagnostics=failures=>failures.map(failure=>summarizeActivationFailureForDiagnostics(failure)).sort((left,right)=>`${left.layer}:${left.name}`.localeCompare(`${right.layer}:${right.name}`)),findActivationFailureByName=(extensionName,failures,layer)=>{const normalizedName=normalizeExtensionNameForMatch(extensionName);return failures.find(failure=>(layer===void 0||failure.layer===layer)&&normalizeExtensionNameForMatch(failure.name)===normalizedName)},resolveInstallRuntimeActivationStatus=(extensionName,scope,runtimeInstalled,installActivationFailure)=>runtimeInstalled.find(entry=>entry.scope===scope&&normalizeExtensionNameForMatch(entry.name)===normalizeExtensionNameForMatch(extensionName))?.activation_status??(installActivationFailure?"failed":"unknown"),probeRuntimeCommandPathsForInstall=(pmRoot,parent,settings,refreshedInstalled,global2)=>extensionRuntimeProbeQueue.enqueue(async()=>{const originalPackageRoot=process.env.PM_CLI_PACKAGE_ROOT,snapshotRoot=await fs.mkdtemp(path.join(parent,".pm-module-graph-"));process.env.PM_CLI_PACKAGE_ROOT=resolvePmPackageRootFromModule(import.meta.url,["../.."]);try{const loadResult=await loadExtensions({pmRoot,settings,cwd:process.cwd(),noExtensions:global2.noExtensions===!0,reload_token:nextExtensionReloadToken(),cache_bust:!0,module_graph_snapshot_root:snapshotRoot}),activationResult=await activateExtensions({...loadResult}),runtimeFailures=[...loadResult.failed.map(failure=>({layer:failure.layer,name:failure.name,entry_path:failure.entry_path,error:failure.error})),...collectActivationFailureDiagnostics(activationResult.failed)],contributionInventories=Object.fromEntries(loadResult.loaded.map(extension=>[normalizeExtensionNameForMatch(extension.name),createExtensionContributionInventory(describeExtensionActivation(activationResult,{extensionName:extension.name}))]));return{installed:applyDoctorRuntimeActivationState(refreshedInstalled,loadResult,activationResult),warnings:[...loadResult.warnings,...activationResult.warnings],activation_failures:runtimeFailures,extensions_disabled:loadResult.disabled_by_flag,item_type_registrations:activationResult.registrations.item_types,contribution_inventories:contributionInventories}}finally{await fs.rm(snapshotRoot,{recursive:!0,force:!0}),originalPackageRoot===void 0?delete process.env.PM_CLI_PACKAGE_ROOT:process.env.PM_CLI_PACKAGE_ROOT=originalPackageRoot}}),adoptUnmanagedExtensions=async(extensionsRoot,scope,installedExtensions,state)=>{const unmanagedCandidates=installedExtensions.filter(entry=>!entry.managed),sortedCandidates=[...unmanagedCandidates].sort((left,right)=>{const byName=left.name.localeCompare(right.name);return byName!==0?byName:left.directory.localeCompare(right.directory)});let nextState=state;const adoptedEntries=[];for(const candidate of sortedCandidates){const extensionDirectory=path.join(extensionsRoot,candidate.directory),validated=await validateExtensionDirectory(extensionDirectory),now=nowIso(),sourceRecord={kind:"local",input:candidate.name,location:extensionDirectory};nextState=upsertManagedEntry(nextState,{name:validated.manifest.name,directory:candidate.directory,scope,manifest_version:validated.manifest.version,manifest_entry:validated.manifest.entry,capabilities:[...validated.manifest.capabilities],contributions:validated.manifest.contributions,installed_at:now,updated_at:now,source:sourceRecord}),adoptedEntries.push({name:validated.manifest.name,directory:candidate.directory,version:validated.manifest.version,entry:validated.manifest.entry,source:sourceRecord})}return adoptedEntries.length>0&&await writeManagedExtensionState(extensionsRoot,nextState),{state:nextState,adopted_entries:adoptedEntries,unmanaged_candidates:sortedCandidates,already_managed_count:installedExtensions.length-unmanagedCandidates.length}},resolveExtensionRootsForScope=(scope,global2)=>{const pmRoot=resolvePmRoot(process.cwd(),global2.path),roots=resolveExtensionRoots(pmRoot,process.cwd()),settingsRoot=scope==="global"?resolveGlobalPmRoot(process.cwd()):pmRoot,selectedRoot=scope==="global"?roots.global:roots.project;return{pm_root:pmRoot,scope,settings_root:settingsRoot,selected_root:selectedRoot,roots}},resolveGithubOption=options=>{const values=[options.gh,options.github].filter(value=>typeof value=="string").map(value=>value.trim()).filter(Boolean),uniqueValues=[...new Set(values)];if(uniqueValues.length>1)throw new PmCliError('Options "--gh" and "--github" must match when both are provided.',EXIT_CODE.USAGE);return uniqueValues[0]},getLifecycleActionFlag=action=>LIFECYCLE_ACTION_FLAGS[action],throwMissingLifecycleTarget=(action,options)=>{const noun=options.vocabulary==="package"?"package":"extension",targetName=action==="install"?"source":"name",targetLabel=`${noun} ${targetName}`,actionFlag=getLifecycleActionFlag(action),commandTarget=`<${targetName}>`,command=`pm ${noun} ${actionFlag} ${commandTarget}`;throw new PmCliError(`Action "${action}" requires ${targetLabel} input.`,EXIT_CODE.USAGE,{code:"missing_lifecycle_target",required:`Provide a ${targetName} target for ${action}.`,examples:[`pm ${noun} ${action} ${commandTarget}`,command,`pm ${noun} --help`],recovery:{attempted_command:`pm ${noun} ${action}`,suggested_retry:command,fallback_candidates:[{source:"lifecycle_action",command,reason:`flag-form ${action} command with required ${targetName} target`}]}})},requireTarget=(target,action,options={})=>{const normalized=target?.trim();if(normalized)return normalized;if(action==="init")throw new PmCliError('Action "init" requires a scaffold target path (for example: pm package init ./my-package or pm extension init ./my-extension).',EXIT_CODE.USAGE);return throwMissingLifecycleTarget(action,options)},collectSchemaNarrowActivationDoctorWarnings=(loadResult,activationResult)=>{const schemaContributors=new Set([...activationResult.registrations.item_types.map(entry=>({entry,count:entry.types.length})),...activationResult.registrations.item_fields.map(entry=>({entry,count:entry.fields.length}))].filter(({count})=>count>0).map(({entry})=>`${entry.layer}:${normalizeExtensionNameForMatch(entry.name)}`));return loadResult.loaded.filter(extension=>(extension.activation?.commands??[]).length>0).filter(extension=>schemaContributors.has(`${extension.layer}:${normalizeExtensionNameForMatch(extension.name)}`)).map(extension=>`extension_schema_narrow_activation:${extension.layer}:${extension.name}`).filter((warning,index,warnings)=>warnings.indexOf(warning)===index).sort((left,right)=>left.localeCompare(right))},assertExtensionActionOptionScope=(action,options)=>{const invalidGuard=[{triggered:options.strictExit===!0||options.failOnWarn===!0,allowed:action==="doctor",message:"--strict-exit and --fail-on-warn are only valid with --doctor."},{triggered:options.trace===!0,allowed:action==="doctor",message:"--trace is only valid with --doctor."},{triggered:options.watch===!0,allowed:action==="reload",message:"--watch is only valid with --reload."},{triggered:options.runtimeProbe===!0,allowed:action==="manage",message:"--runtime-probe is only valid with --manage."},{triggered:options.fixManagedState===!0,allowed:action==="manage"||action==="doctor",message:"--fix-managed-state is only valid with --manage or --doctor."},{triggered:options.isolated===!0||options.ignoreGlobal===!0,allowed:action==="doctor",message:"--isolated and --ignore-global are only valid with --doctor."},{triggered:options.capability!==void 0,allowed:action==="init",message:"--capability is only valid with --init/--scaffold."},{triggered:options.declarative===!0,allowed:action==="init",message:"--declarative is only valid with --init/--scaffold."},{triggered:options.dryRun===!0,allowed:action==="migrate"||action==="install",message:"--dry-run is only valid with --migrate or --install."}].find(guard=>guard.triggered&&!guard.allowed);if(invalidGuard)throw new PmCliError(invalidGuard.message,EXIT_CODE.USAGE)},resolveNormalizedExtensionTarget=(target,action,options)=>{const normalizedInput=String(target??"").trim().toLowerCase(),explicitInitAction=[options.init,options.scaffold].includes(!0);return({doctor:["doctor"],reload:["reload"],catalog:["catalog"],init:explicitInitAction?[]:["init","scaffold"]}[action]??[]).includes(normalizedInput)?void 0:target},resolveExtensionResultRoots=ctx=>[ctx.action==="catalog",typeof ctx.options.fields=="string",String(ctx.options.fields).trim().length>0].every(Boolean)?{project:"project",global:"global",selected:ctx.scope,settings_root:"project"}:{project:ctx.resolvedRoots.roots.project,global:ctx.resolvedRoots.roots.global,selected:ctx.resolvedRoots.selected_root,settings_root:ctx.resolvedRoots.settings_root},buildExtensionActionResult=(ctx,details,ok)=>{const result={ok,action:ctx.action,scope:ctx.scope,roots:resolveExtensionResultRoots(ctx),warnings:[...new Set(ctx.warnings)].sort((left,right)=>left.localeCompare(right)),details};return ctx.action==="doctor"&&Object.defineProperty(result,NATIVE_OUTPUT_MARKER,{value:!0,enumerable:!1,configurable:!1}),result},runExtension=async(target,options,global2)=>{const action=resolveAction(target,options);assertExtensionActionOptionScope(action,options);const normalizedTarget=resolveNormalizedExtensionTarget(target,action,options),scope=resolveScope(options),resolvedRoots=resolveExtensionRootsForScope(scope,global2),actionContext={action,normalizedTarget,scope,resolvedRoots,warnings:[],options,global:global2},ctx={...actionContext,withResult:(details,ok=!0)=>buildExtensionActionResult(actionContext,details,ok)};return await dispatchExtensionAction(ctx)},buildExtensionScaffoldNextSteps=(scaffold,options)=>{const vocabulary=options.vocabulary??"extension",shellTargetPath=scaffold.target_path.replace(/\\/g,"/"),quotedShellTargetPath=quoteCommandArg(shellTargetPath),dependencySteps={package:`Install dependencies: cd ${quotedShellTargetPath}, then run "npm install"`,extension:`Install type-check dependencies: cd ${quotedShellTargetPath}, then run "npm install -D typescript @types/node @unbrained/pm-cli"`},validationSteps={package:`Validate the package: cd ${quotedShellTargetPath}, then run "npm run typecheck" and "npm test"`,extension:`Type-check the source (optional): cd ${quotedShellTargetPath}, then run "npx tsc --noEmit"`},declarativeGuidance=[];return[vocabulary==="package",options.declarative===!0].every(Boolean)&&declarativeGuidance.push("Ensure the target workspace can resolve @unbrained/pm-cli before installing this declarative package."),[dependencySteps[vocabulary],...declarativeGuidance,`Install the scaffold: ${renderPmCommand(vocabulary==="package"?["install","--project",shellTargetPath]:["extension","--install","--project",shellTargetPath])}`,`Smoke-test command path: pm ${scaffold.command_name}`,validationSteps[vocabulary],`Run diagnostics: ${vocabulary==="package"?"pm package doctor":"pm extension --doctor"} --project --detail summary`]},runExtensionInitAction=async ctx=>{const{action,normalizedTarget,options,withResult}=ctx;if([resolveGithubOption(options),options.ref].filter(value=>typeof value=="string").map(value=>value.trim()).filter(Boolean).length>0)throw new PmCliError('Action "init" does not accept --gh/--github/--ref options.',EXIT_CODE.USAGE);const scaffoldTarget=requireTarget(normalizedTarget,action,options),scaffold=await scaffoldExtensionProject(scaffoldTarget,options.vocabulary??"extension",options.capability,options.declarative===!0);return withResult({scaffolded:scaffold.created_directory||scaffold.files.some(entry=>entry.status==="created"),extension:{name:scaffold.extension_name,command:scaffold.command_name},capability:scaffold.capability,style:scaffold.style,target_path:scaffold.target_path,created_directory:scaffold.created_directory,files:scaffold.files,next_steps:buildExtensionScaffoldNextSteps(scaffold,options)})},runExtensionReloadAction=async ctx=>{const{normalizedTarget,resolvedRoots,warnings,options,global:global2,withResult}=ctx;if(normalizedTarget!==void 0)throw new PmCliError('Action "reload" does not accept a target argument.',EXIT_CODE.USAGE);const settings=await readSettings(resolvedRoots.settings_root),reloadToken=nextExtensionReloadToken(),reloaded=await loadExtensions({pmRoot:resolvedRoots.settings_root,settings,cwd:process.cwd(),noExtensions:global2.noExtensions,reload_token:reloadToken,cache_bust:!0});warnings.push(...reloaded.warnings);const activation=await activateExtensions(reloaded);warnings.push(...activation.warnings);const details={reload:{token:reloadToken,cache_bust:!0,watch:options.watch===!0},loaded_count:reloaded.loaded.length,failed_count:reloaded.failed.length,activated_count:Math.max(0,reloaded.loaded.length-activation.failed.length),activation_failed_count:activation.failed.length,loaded_extensions:reloaded.loaded.map(entry=>({name:entry.name,layer:entry.layer,version:entry.version})),failed_extensions:reloaded.failed.map(entry=>({name:entry.name,layer:entry.layer,error:entry.error})),activation_failures:activation.failed.map(entry=>({name:entry.name,layer:entry.layer,error:entry.error}))};return options.watch===!0&&warnings.push("extension_reload_watch_hint:watch_mode_requested_non_interactive_single_pass_only"),withResult(details)},runExtensionCatalogAction=async ctx=>{const{normalizedTarget,scope,options,global:global2,withResult}=ctx;if(typeof normalizedTarget=="string"&&normalizedTarget.length>0&&normalizedTarget!=="catalog")throw new PmCliError('Action "catalog" does not accept a package target.',EXIT_CODE.USAGE);return withResult(await buildBundledPackageCatalog(scope,global2,options))},buildBundledInstallManagedSource=(alias,packageName)=>({kind:"builtin",input:alias,location:alias,name:alias,...packageName===null?{}:{package:packageName}}),buildLocalInstallManagedSource=source=>({kind:"local",input:source.input,location:source.absolute_path}),buildNpmInstallManagedSource=(source,resolved)=>({kind:"npm",input:source.input,location:resolved.resolved_subpath??".",package:resolved.npm_package,version:resolved.npm_version}),buildGithubInstallManagedSource=(source,resolved)=>({kind:"github",input:source.input,location:resolved.resolved_subpath??source.subpath??".",repository:source.repository,owner:source.owner,repo:source.repo,ref:source.ref,subpath:resolved.resolved_subpath??source.subpath,commit:resolved.commit}),buildInstallManagedSource=(bundledAliasName,bundledPackageName,installSource,resolvedSource)=>bundledAliasName?buildBundledInstallManagedSource(bundledAliasName,bundledPackageName):installSource.kind==="local"?buildLocalInstallManagedSource(installSource):installSource.kind==="npm"?buildNpmInstallManagedSource(installSource,resolvedSource):buildGithubInstallManagedSource(installSource,resolvedSource),resolveManagedInstallTimestamps=(existing,manifestVersion,source,now)=>existing?existing.manifest_version!==manifestVersion?{installed_at:existing.installed_at,updated_at:now}:managedExtensionSourcesEquivalent(existing.source,source)?{installed_at:existing.installed_at,updated_at:existing.updated_at}:{installed_at:existing.installed_at,updated_at:now}:{installed_at:now,updated_at:now},persistExtensionInstall=async(ctx,input)=>{const{scope,resolvedRoots,warnings}=ctx,{validated,destinationDirectoryName}=input,settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const destinationDirectory=path.join(resolvedRoots.selected_root,destinationDirectoryName),destinationExists=await pathExists(destinationDirectory),installInPlace=await areDirectoriesEquivalent(validated.directory,destinationDirectory);await fs.mkdir(resolvedRoots.selected_root,{recursive:!0});const backupRoot=await fs.mkdtemp(path.join(resolvedRoots.selected_root,".pm-extension-install-backup-")),backupDirectory=path.join(backupRoot,"destination");try{const snapshot=await captureExtensionInstallSnapshot(resolvedRoots.selected_root,resolvedRoots.settings_root,destinationDirectory,destinationExists,backupDirectory),sourceRecord=buildInstallManagedSource(input.bundledAliasName,input.bundledPackageName,input.installSource,input.resolvedSource),existingManagedEntry=managedStateRead.state.entries.find(entry=>normalizeExtensionNameForMatch(entry.name)===normalizeExtensionNameForMatch(validated.manifest.name)),timestamps=resolveManagedInstallTimestamps(existingManagedEntry,validated.manifest.version,sourceRecord,nowIso()),managedState=upsertManagedEntry(managedStateRead.state,{name:validated.manifest.name,directory:destinationDirectoryName,scope,manifest_version:validated.manifest.version,manifest_entry:validated.manifest.entry,capabilities:[...validated.manifest.capabilities],contributions:validated.manifest.contributions,...timestamps,source:sourceRecord}),activationChanged=ensureActivated(settings,validated.manifest.name);try{installInPlace||await copyExtensionDirectoryForInstall(validated.directory,destinationDirectory),await ensureExtensionModuleTypeMarker(destinationDirectory),await ensureInstalledExtensionSdkLink(destinationDirectory),await writeManagedExtensionState(resolvedRoots.selected_root,managedState),activationChanged&&await writeSettings(resolvedRoots.settings_root,settings,"settings:write")}catch(error){try{await restoreExtensionInstallSnapshot(snapshot)}catch(rollbackError){throw new AggregateError([error,rollbackError],`Extension install failed: ${String(error)}; rollback failed: ${String(rollbackError)}`,{cause:rollbackError})}throw error}return{settings,managedState,sourceRecord,destinationDirectory,destinationExists,installInPlace,activationChanged}}finally{await fs.rm(backupRoot,{recursive:!0,force:!0}).catch(()=>{})}},scaffoldInstalledExtensionItemTypes=async(ctx,extensionName,registrations)=>{const definitions=registrations.filter(entry=>normalizeExtensionNameForMatch(entry.name)===normalizeExtensionNameForMatch(extensionName)).flatMap(entry=>entry.types.map(type=>({name:type.name,folder:type.folder})));return ctx.scope==="project"&&definitions.length>0&&await ensureTypeFolderScaffold(ctx.resolvedRoots.pm_root,definitions,ctx.warnings,"install:type-folder"),definitions},buildInstalledExtensionActivation=(ctx,extensionName,runtimeProbe,commandSummary,installedItemTypes)=>{const failure=findActivationFailureByName(extensionName,runtimeProbe.activation_failures,ctx.scope),status=resolveInstallRuntimeActivationStatus(extensionName,ctx.scope,runtimeProbe.installed,failure),activated=[!runtimeProbe.extensions_disabled,status==="ok"].every(Boolean);activated||ctx.warnings.push(`extension_install_activation_failed:${ctx.scope}:${extensionName}:${status}`);const healthByActivation={true:{status:"ok",blocking_failure_count:0},false:{status:"degraded",blocking_failure_count:1}};return{activated,status,failure,verification:{status:healthByActivation[String(activated)].status,target_pm_root:ctx.resolvedRoots.pm_root,activation_status:status,activated,registered_commands:commandSummary.command_paths,registered_actions:commandSummary.action_paths,registered_item_types:installedItemTypes,module_graph_verification:"fresh_in_topology_snapshot",health:healthByActivation[String(activated)]}}},performExtensionInstallUnderLock=async(ctx,input)=>{const{scope,resolvedRoots,warnings,global:global2,withResult}=ctx,{validated,destinationDirectoryName}=input,persisted=await persistExtensionInstall(ctx,input),refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,persisted.settings,persisted.managedState);warnings.push(...refreshedInstalled.warnings);const runtimeProbe=await probeRuntimeCommandPathsForInstall(resolvedRoots.pm_root,path.dirname(resolvedRoots.selected_root),persisted.settings,refreshedInstalled.extensions,global2);warnings.push(...runtimeProbe.warnings);const installedItemTypeDefinitions=await scaffoldInstalledExtensionItemTypes(ctx,validated.manifest.name,runtimeProbe.item_type_registrations),commandSummary=summarizeRuntimeCommandPathsForExtension(validated.manifest.name,runtimeProbe.installed),activation=buildInstalledExtensionActivation(ctx,validated.manifest.name,runtimeProbe,commandSummary,installedItemTypeDefinitions),contributionInventory=runtimeProbe.contribution_inventories[normalizeExtensionNameForMatch(validated.manifest.name)];return contributionInventory&&(persisted.managedState=await persistManagedContributionInventory(resolvedRoots.selected_root,persisted.managedState,validated.manifest.name,contributionInventory)),withResult({extension:{name:validated.manifest.name,version:validated.manifest.version,entry:validated.manifest.entry,capabilities:validated.manifest.capabilities,directory:destinationDirectoryName},source:persisted.sourceRecord,source_resolution:input.sourceResolution,...input.installPlan?{install_plan:input.installPlan}:{},destination_path:persisted.destinationDirectory,overwritten:[persisted.destinationExists,!persisted.installInPlace].every(Boolean),installed_in_place:persisted.installInPlace,activated:activation.activated,settings_changed:persisted.activationChanged,runtime_activation_status:activation.status,command_paths:commandSummary.command_paths,action_paths:commandSummary.action_paths,contributions:contributionInventory,command_discovery:buildInstallCommandDiscovery(validated.manifest.name,persisted.sourceRecord,commandSummary,activation.failure),verification:activation.verification,activation_diagnostics:{failed_count:runtimeProbe.activation_failures.length,failed:runtimeProbe.activation_failures,installed_extension_failed:activation.failure??null}},activation.activated)},runBundledExtensionInstallAll=async ctx=>{const{options,global:global2,warnings,withResult}=ctx;if(typeof options.ref=="string"&&options.ref.trim().length>0)throw new PmCliError('Action "install all" does not accept --ref.',EXIT_CODE.USAGE);const packages=[],installedSources=new Map;for(const alias of await listBundledPackageAliases()){const source=await resolveBundledExtensionAliasSource(alias),sourceKey=path.resolve(source);let result=installedSources.get(sourceKey);result===void 0&&(result=await runExtension(alias,{...options,install:!0},global2),installedSources.set(sourceKey,result)),packages.push({alias,result})}return warnings.push(...packages.flatMap(entry=>entry.result.warnings)),withResult(buildBundledInstallReceipt(packages,options.dryRun===!0),packages.every(entry=>entry.result.ok))},runSingleExtensionInstall=async(ctx,explicitSourceInput,githubOption)=>{const{resolvedRoots}=ctx,{bundledAliasName,bundledPackageName,installSource,sourceResolution}=await resolveExtensionInstallSourceIdentity(explicitSourceInput,githubOption,ctx.options.ref);if(sourceResolution.ambiguous){const npmCandidate=sourceResolution.candidates.find(candidate=>candidate.kind==="npm");ctx.warnings.push(`extension_install_source_ambiguous:${explicitSourceInput}:builtin:${bundledAliasName}:npm:${npmCandidate.package}`)}const resolvedSource=await resolveInstallSource(installSource);try{const validated=await validateExtensionDirectory(resolvedSource.directory,{source_kind:installSource.kind,source_input:installSource.input,source_root:resolvedSource.source_root}),destinationDirectoryName=normalizeManagedDirectoryName(validated.manifest.name),installPlan=ctx.options.dryRun===!0||installSource.kind==="local"&&bundledAliasName===null?await buildExtensionInstallPlan(resolvedSource,path.join(resolvedRoots.selected_root,destinationDirectoryName),ctx.scope,ctx.options.copyPlan):void 0;return ctx.options.dryRun===!0?ctx.withResult({dry_run:!0,installed:!1,activated:!1,extension:{name:validated.manifest.name,version:validated.manifest.version},source_resolution:sourceResolution,install_plan:installPlan}):await withExtensionInstallLock(resolvedRoots.settings_root,destinationDirectoryName,()=>performExtensionInstallUnderLock(ctx,{validated,destinationDirectoryName,bundledAliasName,bundledPackageName,sourceResolution,installSource,resolvedSource,installPlan}))}finally{resolvedSource.cleanup&&await resolvedSource.cleanup()}},runExtensionInstallAction=async ctx=>{const githubOption=resolveGithubOption(ctx.options),explicitSourceInput=githubOption??requireTarget(ctx.normalizedTarget,ctx.action,ctx.options);return[githubOption===void 0,isBundledPackageInstallAllTarget(explicitSourceInput)].every(Boolean)?runBundledExtensionInstallAll(ctx):runSingleExtensionInstall(ctx,explicitSourceInput,githubOption)},runExtensionAdoptAllAction=async ctx=>{const{normalizedTarget,scope,resolvedRoots,warnings,options,withResult}=ctx;if(normalizedTarget!==void 0)throw new PmCliError('Action "adopt-all" does not accept a target argument.',EXIT_CODE.USAGE);if(resolveGithubOption(options)!==void 0||typeof options.ref=="string"&&options.ref.trim().length>0)throw new PmCliError('Action "adopt-all" does not accept --gh/--github/--ref options.',EXIT_CODE.USAGE);const settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const adoption=await adoptUnmanagedExtensions(resolvedRoots.selected_root,scope,installed.extensions,managedStateRead.state),refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,adoption.state);warnings.push(...refreshedInstalled.warnings);const triage=buildExtensionTriageSummary(scope,warnings,refreshedInstalled.extensions,options);warnings.push(...triage.warnings);const refreshedByIdentity=new Map(refreshedInstalled.extensions.map(entry=>[`${normalizeExtensionNameForMatch(entry.name)}:${normalizeExtensionNameForMatch(entry.directory)}`,entry])),refreshedByDirectory=new Map(refreshedInstalled.extensions.map(entry=>[normalizeExtensionNameForMatch(entry.directory),entry])),adoptedDetails=adoption.adopted_entries.map(entry=>{const normalizedDirectory=normalizeExtensionNameForMatch(entry.directory),refreshedEntry=refreshedByIdentity.get(`${normalizeExtensionNameForMatch(entry.name)}:${normalizedDirectory}`)??refreshedByDirectory.get(normalizedDirectory);return{...entry,...projectExtensionUpdateCheck(refreshedEntry)}});return withResult({adopted_all:adoptedDetails.length>0,adopted_count:adoptedDetails.length,already_managed_count:adoption.already_managed_count,extensions:adoptedDetails,triage,warning_codes:triage.warning_codes,update_health_partial:triage.update_health_partial,update_health_coverage:triage.update_health_coverage})},projectExtensionUpdateCheck=entry=>({update_check_status:entry?.update_check_status??null,update_check_reason:entry?.update_check_reason??null}),buildAdoptedExtensionSource=(githubOption,extensionTarget,extensionDirectory,ref)=>{if(githubOption===void 0)return{kind:"local",input:extensionTarget,location:extensionDirectory};const parsed=parseExtensionInstallSource(githubOption,{forceGithub:!0,ref});if(parsed.kind!=="github")throw new PmCliError(`Invalid GitHub shorthand "${githubOption}".`,EXIT_CODE.USAGE);return{kind:"github",input:parsed.input,location:parsed.subpath??".",repository:parsed.repository,owner:parsed.owner,repo:parsed.repo,ref:parsed.ref,subpath:parsed.subpath}},runExtensionAdoptAction=async ctx=>{const{action,normalizedTarget,scope,resolvedRoots,warnings,options,withResult}=ctx,extensionTarget=requireTarget(normalizedTarget,action,options),githubOption=resolveGithubOption(options),settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const candidate=await resolveInstalledExtensionCandidate(installed.extensions,extensionTarget);if(!candidate)throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`,EXIT_CODE.NOT_FOUND);if(candidate.managed)return withResult({adopted:!1,already_managed:!0,extension:{name:candidate.name,directory:candidate.directory}});const extensionDirectory=path.join(resolvedRoots.selected_root,candidate.directory),validated=await validateExtensionDirectory(extensionDirectory),now=nowIso(),sourceRecord=buildAdoptedExtensionSource(githubOption,extensionTarget,extensionDirectory,options.ref),managedState=upsertManagedEntry(managedStateRead.state,{name:validated.manifest.name,directory:candidate.directory,scope,manifest_version:validated.manifest.version,manifest_entry:validated.manifest.entry,capabilities:[...validated.manifest.capabilities],contributions:validated.manifest.contributions,installed_at:now,updated_at:now,source:sourceRecord});await writeManagedExtensionState(resolvedRoots.selected_root,managedState);const refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedState);warnings.push(...refreshedInstalled.warnings);const refreshedEntry=refreshedInstalled.extensions.find(entry=>normalizeExtensionNameForMatch(entry.name)===normalizeExtensionNameForMatch(validated.manifest.name))??refreshedInstalled.extensions.find(entry=>normalizeExtensionNameForMatch(entry.directory)===normalizeExtensionNameForMatch(candidate.directory));return withResult({adopted:!0,extension:{name:validated.manifest.name,directory:candidate.directory,version:validated.manifest.version,entry:validated.manifest.entry},source:sourceRecord,...projectExtensionUpdateCheck(refreshedEntry)})},resolveRequiredInstalledExtension=async ctx=>{const{action,normalizedTarget,scope,resolvedRoots,warnings,options}=ctx,extensionTarget=requireTarget(normalizedTarget,action,options),settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const candidate=await resolveInstalledExtensionCandidate(installed.extensions,extensionTarget);if(!candidate)throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`,EXIT_CODE.NOT_FOUND);return{settings,managedStateRead,candidate}},runExtensionUninstallAction=async ctx=>{const{resolvedRoots,withResult}=ctx,{settings,managedStateRead,candidate}=await resolveRequiredInstalledExtension(ctx),destinationDirectory=path.join(resolvedRoots.selected_root,candidate.directory);await fs.rm(destinationDirectory,{recursive:!0,force:!0});const updatedState={...managedStateRead.state,updated_at:nowIso(),entries:managedStateRead.state.entries.filter(entry=>normalizeExtensionNameForMatch(entry.name)!==normalizeExtensionNameForMatch(candidate.name)&&normalizeExtensionNameForMatch(entry.directory)!==normalizeExtensionNameForMatch(candidate.directory))};await writeManagedExtensionState(resolvedRoots.selected_root,updatedState);const stateChanged=clearExtensionState(settings,candidate.name);return stateChanged&&await writeSettings(resolvedRoots.settings_root,settings,"settings:write"),withResult({removed:!0,extension:{name:candidate.name,directory:candidate.directory},destination_path:destinationDirectory,settings_changed:stateChanged})},runExtensionActivateDeactivateAction=async ctx=>{const{action,resolvedRoots,warnings,global:global2,withResult}=ctx,{settings,candidate}=await resolveRequiredInstalledExtension(ctx),settingsChanged=action==="activate"?ensureActivated(settings,candidate.name):ensureDeactivated(settings,candidate.name);settingsChanged&&await writeSettings(resolvedRoots.settings_root,settings,"settings:write");const activationFailure=action==="activate"?await probeRuntimeCommandPathsForInstall(resolvedRoots.pm_root,path.dirname(resolvedRoots.selected_root),settings,[candidate],global2).then(probe=>(warnings.push(...probe.warnings),findActivationFailureByName(candidate.name,probe.activation_failures,ctx.scope))):void 0;return activationFailure&&warnings.push(`extension_activate_failed:${ctx.scope}:${candidate.name}`),withResult({extension:{name:candidate.name,directory:candidate.directory},active:action==="activate"&&activationFailure===void 0,runtime_active:action==="activate"&&activationFailure===void 0,activation_failure:activationFailure??null,settings_changed:settingsChanged,settings:{enabled:[...settings.extensions.enabled],disabled:[...settings.extensions.disabled]}},activationFailure===void 0)},buildDoctorRemediation=(baseRemediation,loadFailureCount,activationFailureCount,vocabulary,managedStateFix,isolationHint)=>{const noun=vocabulary==="package"?"package":"extension",doctorAction={package:"doctor",extension:"--doctor"}[noun],adoptedCount=managedStateFix?.adopted_entries.length??0,conditionalEntries=[[isolationHint!==null,isolationHint??""],[loadFailureCount>0,`Run pm ${noun} explore --project and pm ${noun} explore --global to inspect load failures.`],[activationFailureCount>0,`Review activation failures in pm ${noun} ${doctorAction} --detail deep output.`],[adoptedCount>0,`Managed-state fix adopted ${adoptedCount} extension(s).`]];return[...new Set([...baseRemediation,...conditionalEntries.filter(([include])=>include).map(([,entry])=>entry)].map(entry=>entry.trim()).filter(entry=>entry.length>0))]},hasGlobalLayerDiagnostics=loadResult=>loadResult.loaded.some(entry=>entry.layer==="global")||loadResult.failed.some(entry=>entry.layer==="global")||loadResult.warnings.some(warning=>warning.includes(":global:")),buildDoctorIsolationHint=(scope,isolated,vocabulary,loadResult)=>{if(scope!=="project"||isolated||!hasGlobalLayerDiagnostics(loadResult))return null;const noun=vocabulary==="package"?"package":"extension";return`Global ${noun} registrations are included in project diagnostics. For hermetic ${noun} smoke tests, rerun pm ${noun} doctor --project --isolated --detail deep --trace, or set PM_GLOBAL_PATH to a temporary directory for the whole test process.`},resolveDoctorInvocationOptions=(target,scope,options)=>{if(String(target??"").trim().length>0)throw new PmCliError('Action "doctor" does not accept a target argument.',EXIT_CODE.USAGE);const isolated=[options.isolated,options.ignoreGlobal].includes(!0);if([isolated,scope==="global"].every(Boolean))throw new PmCliError("--isolated and --ignore-global are only valid with project-scope doctor diagnostics.",EXIT_CODE.USAGE);const detailMode=parseDoctorDetailMode(options.detail),includeTrace=options.trace===!0;if([includeTrace,detailMode!=="deep"].every(Boolean))throw new PmCliError("--trace requires --detail deep with --doctor.",EXIT_CODE.USAGE);return{isolated,detailMode,includeTrace}},applyDoctorManagedStateFix=async(ctx,installed,state)=>{if(ctx.options.fixManagedState!==!0)return{state,fix:null};const fix=await adoptUnmanagedExtensions(ctx.resolvedRoots.selected_root,ctx.scope,installed,state);return{state:fix.state,fix}},buildDoctorIsolationMetadata=(scope,isolated,vocabulary,loadResult)=>{const noun=vocabulary==="package"?"package":"extension";if(scope!=="project")return{isolated,global_extensions_included:!1,global_diagnostics_present:hasGlobalLayerDiagnostics(loadResult),rerun_command:null,pm_global_path_recipe:null};const isolatedCommand=`pm ${noun} doctor --project --isolated --detail deep --trace`;return{isolated,global_extensions_included:!isolated,global_diagnostics_present:hasGlobalLayerDiagnostics(loadResult),rerun_command:isolated?null:isolatedCommand,pm_global_path_recipe:`PM_GLOBAL_PATH=$(mktemp -d) pm ${noun} doctor --project --detail deep --trace`}},runExtensionDoctorAction=async ctx=>{const{normalizedTarget,scope,resolvedRoots,warnings,options,global:global2,withResult}=ctx,{isolated,detailMode,includeTrace}=resolveDoctorInvocationOptions(normalizedTarget,scope,options),settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const{state:managedState,fix:managedStateFix}=await applyDoctorManagedStateFix(ctx,installed.extensions,managedStateRead.state),refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedState);warnings.push(...refreshedInstalled.warnings);const loadResult=await loadExtensions({pmRoot:resolvedRoots.pm_root,settings,cwd:process.cwd(),noExtensions:global2.noExtensions===!0,ignoreGlobalExtensions:isolated}),activationResult=await activateExtensions({...loadResult,loaded:loadResult.loaded}),authorManifest=await inspectExtensionAuthorManifestAtPmRoot(resolvedRoots.pm_root);warnings.push(...authorManifest.warnings,...loadResult.warnings),warnings.push(...classifyDoctorLoadFailureWarnings(loadResult.failed)),warnings.push(...activationResult.warnings),warnings.push(...classifyDoctorActivationFailureWarnings(activationResult.failed)),warnings.push(...classifyUnusedCapabilityWarnings(loadResult,activationResult)),warnings.push(...collectGlobalOutputOverrideDoctorWarnings(activationResult,loadResult)),warnings.push(...collectSchemaNarrowActivationDoctorWarnings(loadResult,activationResult)),warnings.push(...collectMcpCustomFieldCollisionDoctorWarnings(activationResult));const runtimeInstalledExtensions=applyDoctorRuntimeActivationState(refreshedInstalled.extensions,loadResult,activationResult),doctorConsistency=buildDoctorConsistencySummary(scope,runtimeInstalledExtensions,loadResult.loaded.map(entry=>({layer:entry.layer,name:entry.name})),loadResult.failed.map(entry=>({name:entry.name})),loadResult.disabled_by_flag);warnings.push(...doctorConsistency.warnings);const updateCheckWarnings=runtimeInstalledExtensions.filter(entry=>entry.update_check_status==="failed").map(entry=>`extension_update_check_failed:${entry.name}`);warnings.push(...updateCheckWarnings);const triage=buildExtensionTriageSummary(scope,warnings,runtimeInstalledExtensions,options);warnings.push(...triage.warnings);const normalizedWarnings=[...triage.warnings],policySummary={mode:loadResult.policy.mode,trust_mode:loadResult.policy.trust_mode,require_provenance:loadResult.policy.require_provenance,default_sandbox_profile:loadResult.policy.default_sandbox_profile,sandbox_enforcement:"advisory: sandbox_profile/permissions are declaration-based load gates, not runtime isolation (ADR pm-6ef3)",trusted_extensions_count:loadResult.policy.trusted_extensions.length,allowed_extensions_count:loadResult.policy.allowed_extensions.length,blocked_extensions_count:loadResult.policy.blocked_extensions.length,allowed_capabilities_count:loadResult.policy.allowed_capabilities.length,blocked_capabilities_count:loadResult.policy.blocked_capabilities.length,allowed_surfaces_count:loadResult.policy.allowed_surfaces.length,blocked_surfaces_count:loadResult.policy.blocked_surfaces.length,allowed_commands_count:loadResult.policy.allowed_commands.length,blocked_commands_count:loadResult.policy.blocked_commands.length,allowed_actions_count:loadResult.policy.allowed_actions.length,blocked_actions_count:loadResult.policy.blocked_actions.length,allowed_services_count:loadResult.policy.allowed_services.length,blocked_services_count:loadResult.policy.blocked_services.length,extension_override_count:loadResult.policy.extension_overrides.length},capabilityGuidance=collectUnknownCapabilityGuidance(normalizedWarnings),capabilityContract=buildCapabilityContractMetadata(),warningCodes=triage.warning_codes,isolationHint=buildDoctorIsolationHint(scope,isolated,options.vocabulary,loadResult),remediation=buildDoctorRemediation(triage.remediation,loadResult.failed.length,activationResult.failed.length,options.vocabulary,managedStateFix,isolationHint),isolation=buildDoctorIsolationMetadata(scope,isolated,options.vocabulary,loadResult),summary={status:triage.status,scope,warning_count:triage.warning_count,warning_codes:warningCodes,total_extensions:runtimeInstalledExtensions.length,managed_total:runtimeInstalledExtensions.filter(entry=>entry.managed).length,enabled_total:runtimeInstalledExtensions.filter(entry=>entry.enabled).length,active_total:runtimeInstalledExtensions.filter(entry=>entry.active).length,unmanaged_loaded_extension_count:triage.unmanaged_loaded_extension_count,unmanaged_action_required_extension_count:triage.unmanaged_action_required_extension_count,unmanaged_expected_extension_count:triage.unmanaged_expected_extension_count,runtime_active_total:runtimeInstalledExtensions.filter(entry=>entry.runtime_active===!0).length,activation_status_totals:{ok:runtimeInstalledExtensions.filter(entry=>entry.activation_status==="ok").length,failed:runtimeInstalledExtensions.filter(entry=>entry.activation_status==="failed").length,not_loaded:runtimeInstalledExtensions.filter(entry=>entry.activation_status==="not_loaded").length,unknown:runtimeInstalledExtensions.filter(entry=>entry.activation_status==="unknown").length},unknown_capability_count:capabilityGuidance.length,capability_contract_version:capabilityContract.version,update_available_total:triage.update_available_total,update_check_status_totals:triage.update_check_status_totals,update_health_coverage:triage.update_health_coverage,update_health_partial:triage.update_health_partial,update_check_failed_total:runtimeInstalledExtensions.filter(entry=>entry.update_check_status==="failed").length,load_failure_count:loadResult.failed.length,activation_failure_count:activationResult.failed.length,load_failures:summarizeExtensionFailures(loadResult.failed),activation_failures:summarizeExtensionFailures(activationResult.failed),blocking_failure_count:loadResult.failed.length+activationResult.failed.length,has_blocking_failures:loadResult.failed.length+activationResult.failed.length>0,consistency_warning_count:doctorConsistency.warnings.length,trace_enabled:includeTrace,isolation,policy:policySummary,remediation},managedStateFixSummary=managedStateFix?{requested:!0,applied:managedStateFix.adopted_entries.length>0,adopted_count:managedStateFix.adopted_entries.length,already_managed_count:managedStateFix.already_managed_count,adopted_extensions:managedStateFix.adopted_entries.map(entry=>entry.name)}:{requested:!1,applied:!1,adopted_count:0,already_managed_count:refreshedInstalled.extensions.filter(entry=>entry.managed).length,adopted_extensions:[]},details={mode:detailMode,summary,triage,trace_enabled:includeTrace,capability_contract:capabilityContract,capability_guidance:capabilityGuidance,managed_state_fix:managedStateFixSummary,author_manifest:authorManifest,isolation,policy:loadResult.policy};if(detailMode==="deep"){const activationFailedDetails=includeTrace?activationResult.failed:activationResult.failed.map(entry=>{const{trace:_trace,...rest}=entry;return rest});details.deep={warnings:normalizedWarnings,warning_codes:warningCodes,capability_contract:capabilityContract,capability_guidance:capabilityGuidance,trace_enabled:includeTrace,managed_state:{path:managedStateRead.path,count:managedState.entries.length,entries:managedState.entries},installed_extensions:runtimeInstalledExtensions,load:{roots:loadResult.roots,policy:loadResult.policy,warnings:loadResult.warnings,failed:loadResult.failed,loaded:loadResult.loaded.map(entry=>({layer:entry.layer,directory:entry.directory,name:entry.name,version:entry.version,entry:entry.entry,priority:entry.priority}))},activation:{failed:activationFailedDetails,warnings:activationResult.warnings,hook_counts:activationResult.hook_counts,registration_counts:activationResult.registration_counts,parser_override_count:activationResult.parser_override_count,preflight_override_count:activationResult.preflight_override_count,service_override_count:activationResult.service_override_count,renderer_override_count:activationResult.renderer_override_count},consistency:doctorConsistency.summary},includeTrace&&(details.deep.trace={activation_failures:activationResult.failed.filter(entry=>entry.trace!==void 0).map(entry=>({layer:entry.layer,name:entry.name,entry_path:entry.entry_path,error:entry.error,method:entry.trace.method,command:entry.trace.command,capability:entry.trace.capability,missing_capability:entry.trace.missing_capability,registration_index:entry.trace.registration_index,expected_schema:entry.trace.expected_schema,hint:entry.trace.hint,received:entry.trace.received}))})}return withResult(details)},runExtensionDescribeAction=async ctx=>{const{normalizedTarget,scope,resolvedRoots,warnings,options,global:global2,withResult}=ctx,settings=await readSettings(resolvedRoots.settings_root),loadResult=await loadExtensions({pmRoot:resolvedRoots.pm_root,settings,cwd:process.cwd(),noExtensions:global2.noExtensions===!0}),activationResult=await activateExtensions(loadResult);warnings.push(...loadResult.warnings),warnings.push(...activationResult.warnings);const describeResult=buildExtensionDescribeResult(normalizedTarget,loadResult,activationResult);if(normalizedTarget!==void 0&&describeResult.extensions.length===0){const noun=options.vocabulary==="package"?"package":"extension",loadedNames=[...new Set(loadResult.loaded.map(entry=>options.vocabulary==="package"&&typeof entry.source_package=="string"&&entry.source_package.trim().length>0?entry.source_package.trim():entry.name))].sort((left,right)=>left.localeCompare(right)),loadedHint=loadedNames.length>0?` Loaded ${noun} names: ${loadedNames.join(", ")}.`:"";throw new PmCliError(`No loaded ${noun} named "${normalizedTarget}" was found in ${scope} scope.${loadedHint} Run pm ${noun} explore to list discovered ${noun}s.`,EXIT_CODE.NOT_FOUND)}return withResult({target:describeResult.target,total:describeResult.total,extensions:describeResult.extensions,union:describeResult.union,command_ownership:describeResult.command_ownership})},prepareExploreManageState=async(ctx,installed,initialState)=>{let state=initialState,fix=null;if([ctx.action==="manage",ctx.options.fixManagedState===!0].every(Boolean)&&(fix=await adoptUnmanagedExtensions(ctx.resolvedRoots.selected_root,ctx.scope,installed,initialState),state=fix.state),ctx.action==="manage"){const entries=await mapWithFixedConcurrency(state.entries,GITHUB_UPDATE_CHECK_CONCURRENCY,async entry=>{if(entry.source.kind!=="github")return entry;const updateStatus=await checkGithubUpdate(entry.source);return{...entry,last_update_check_at:updateStatus.checked_at,last_update_remote_commit:updateStatus.remote_commit,update_available:updateStatus.available,update_error:updateStatus.error}});state={...state,updated_at:nowIso(),entries:sortManagedEntries(entries)},await writeManagedExtensionState(ctx.resolvedRoots.selected_root,state)}return{state,fix}},probeExploreManageRuntime=async(ctx,settings,installed)=>{const loadResult=await loadExtensions({pmRoot:ctx.resolvedRoots.pm_root,settings,cwd:process.cwd(),noExtensions:ctx.global.noExtensions===!0}),activationResult=await activateExtensions({...loadResult,loaded:loadResult.loaded});return ctx.warnings.push(...loadResult.warnings,...activationResult.warnings),{installed:applyDoctorRuntimeActivationState(installed,loadResult,activationResult),failures:collectActivationFailureDiagnostics(activationResult.failed),summary:{requested:!0,executed:!0,reason:ctx.action==="explore"?"explore_defaults_to_runtime_probe":ctx.options.runtimeProbe===!0?"runtime_probe_requested":"manage_defaults_to_runtime_probe",load_failure_count:loadResult.failed.length,activation_failure_count:activationResult.failed.length,warning_count:[...new Set([...loadResult.warnings,...activationResult.warnings])].length,policy:loadResult.policy}}},projectExploreManageFix=(fix,installed)=>fix?{requested:!0,applied:fix.adopted_entries.length>0,adopted_count:fix.adopted_entries.length,adopted_extensions:fix.adopted_entries.map(entry=>entry.name),already_managed_count:fix.already_managed_count}:{requested:!1,applied:!1,adopted_count:0,adopted_extensions:[],already_managed_count:installed.filter(entry=>entry.managed).length},runExtensionExploreManageAction=async ctx=>{const{action,scope,resolvedRoots,warnings,options,withResult}=ctx,settings=await readSettings(resolvedRoots.settings_root),configuredPolicy=buildExtensionPolicyDetails(settings.extensions.policy),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const{state:managedState,fix:managedStateFix}=await prepareExploreManageState(ctx,installed.extensions,managedStateRead.state),refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedState);if(warnings.push(...refreshedInstalled.warnings),action==="manage"){const updateWarnings=refreshedInstalled.extensions.filter(entry=>entry.update_check_status==="failed").map(entry=>`extension_update_check_failed:${entry.name}`);warnings.push(...updateWarnings)}const runtimeProbe=await probeExploreManageRuntime(ctx,settings,refreshedInstalled.extensions),runtimeInstalledExtensions=runtimeProbe.installed,triage=buildExtensionTriageSummary(scope,warnings,runtimeInstalledExtensions,options);warnings.push(...triage.warnings);const details={total:runtimeInstalledExtensions.length,managed_total:runtimeInstalledExtensions.filter(entry=>entry.managed).length,enabled_total:runtimeInstalledExtensions.filter(entry=>entry.enabled).length,active_total:runtimeInstalledExtensions.filter(entry=>entry.active).length,extensions:runtimeInstalledExtensions,triage,policy:configuredPolicy};return runtimeProbe.failures!==void 0&&(details.activation_diagnostics={failed_count:runtimeProbe.failures.length,failed:runtimeProbe.failures}),action==="explore"&&(details.runtime_probe=runtimeProbe.summary),action==="manage"&&(details.runtime_probe=runtimeProbe.summary,details.managed_state_fix=projectExploreManageFix(managedStateFix,runtimeInstalledExtensions)),withResult(details)},EXTENSION_ACTION_HANDLERS={init:runExtensionInitAction,install:runExtensionInstallAction,uninstall:runExtensionUninstallAction,explore:runExtensionExploreManageAction,manage:runExtensionExploreManageAction,describe:runExtensionDescribeAction,reload:runExtensionReloadAction,doctor:runExtensionDoctorAction,catalog:runExtensionCatalogAction,adopt:runExtensionAdoptAction,"adopt-all":runExtensionAdoptAllAction,activate:runExtensionActivateDeactivateAction,deactivate:runExtensionActivateDeactivateAction,migrate:runExtensionMigrateAction},requiresExtensionStateLock=ctx=>[ctx.action==="uninstall",ctx.action==="manage",ctx.action==="adopt",ctx.action==="adopt-all",ctx.action==="activate",ctx.action==="deactivate",ctx.action==="migrate",[ctx.action==="doctor",ctx.options.fixManagedState===!0].every(Boolean)].some(Boolean),dispatchExtensionAction=ctx=>requiresExtensionStateLock(ctx)?withExtensionInstallLock(ctx.resolvedRoots.settings_root,`${ctx.action}-state`,()=>EXTENSION_ACTION_HANDLERS[ctx.action](ctx)):EXTENSION_ACTION_HANDLERS[ctx.action](ctx),_testOnly={adoptUnmanagedExtensions,buildAdoptedExtensionSource,buildExtensionPolicyDetails,buildInstallCommandDiscovery,checkGithubUpdate,clearExtensionState,collectActivationFailureDiagnostics,findActivationFailureByName,resolveInstallRuntimeActivationStatus,collectGlobalOutputOverrideDoctorWarnings,collectMcpCustomFieldCollisionDoctorWarnings,collectSchemaNarrowActivationDoctorWarnings,copyExtensionDirectoryWithoutSelfNesting,isErrnoCode,isRetriableExtensionInstallCopyError,listInstalledExtensions,mapWithFixedConcurrency,projectExtensionUpdateCheck,readOptionalMetadataFile,requireTarget,resolveAction,resolveCommandDiscoveryPackageName,resolveGithubOption,resolveInstalledExtensionCandidate,resolveManagedInstallTimestamps,resolveScope,resolveUpdateCheckResolution,withExtensionInstallLock};export{_testOnly,copyExtensionDirectoryForInstall,parseExtensionInstallSource,parseExtensionManifest,readManagedExtensionState,resolveCanonicalExtensionInstallDestination,resolveManagedExtensionStatePath,runExtension,validateExtensionDirectory,writeManagedExtensionState};
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]="549164da-d760-52bc-9950-25dacf286775")}catch{}})();import fs from"node:fs/promises";import path from"node:path";import{activateExtensions,createSerialQueue,loadExtensions,nextExtensionReloadToken}from"../core/extensions/index.js";import{describeExtensionActivation}from"../core/extensions/activation-summary.js";import{createExtensionContributionInventory}from"../core/extensions/contribution-inventory.js";import{resolveExtensionRoots}from"../core/extensions/loader.js";import{pathExists}from"../core/fs/fs-utils.js";import{resolvePmPackageRootFromModule}from"../core/packages/root.js";import{EXIT_CODE}from"../core/shared/constants.js";import{PmCliError}from"../core/shared/errors.js";import{levenshteinDistanceWithinLimit}from"../core/shared/levenshtein.js";import{nowIso}from"../core/shared/time.js";import{resolveGlobalPmRoot,resolvePmRoot}from"../core/store/paths.js";import{readSettings,writeSettings}from"../core/store/settings.js";import{quoteCommandArg,renderPmCommand}from"./command-line.js";import{createUnknownSubcommandError}from"./agent/subcommand-recovery.js";import{ensureTypeFolderScaffold}from"./schema.js";import{normalizeStringList,normalizeExtensionNameForMatch,normalizeManagedDirectoryName,parseExtensionManifest,validateExtensionDirectory}from"./extension/shared.js";import{managedExtensionSourcesEquivalent,readManagedExtensionState,writeManagedExtensionState,upsertManagedEntry,persistManagedContributionInventory,resolveManagedExtensionStatePath}from"./extension/managed-state.js";import{parseExtensionInstallSource,resolveInstallSource,areDirectoriesEquivalent}from"./extension/install-sources.js";import{resolveBundledExtensionAliasSource,isBundledPackageInstallAllTarget,listBundledPackageAliases,resolveBundledAliasManifestName,buildBundledPackageCatalog}from"./extension/bundled-catalog.js";import{scaffoldExtensionProject}from"./extension/scaffold.js";import{buildExtensionDescribeResult}from"./extension/describe.js";import{applyDoctorRuntimeActivationState,classifyDoctorLoadFailureWarnings,classifyDoctorActivationFailureWarnings,classifyUnusedCapabilityWarnings,buildExtensionTriageSummary,parseDoctorDetailMode,collectUnknownCapabilityGuidance,buildCapabilityContractMetadata,buildDoctorConsistencySummary,summarizeExtensionFailures}from"./extension/doctor.js";import{copyExtensionDirectoryForInstall,copyExtensionDirectoryWithoutSelfNesting,ensureExtensionModuleTypeMarker,ensureInstalledExtensionSdkLink,isErrnoCode,isRetriableExtensionInstallCopyError,resolveCanonicalExtensionInstallDestination,withExtensionInstallLock}from"./extension/install-runtime.js";import{mapWithFixedConcurrency}from"./extension/concurrency.js";import{summarizeRuntimeCommandPathsForExtension}from"./extension/runtime-summary.js";import{collectGlobalOutputOverrideDoctorWarnings}from"./extension/output-ownership.js";import{collectMcpCustomFieldCollisionDoctorWarnings}from"./extension/custom-field-collisions.js";import{checkGithubUpdate}from"./extension/update-check.js";import{refreshManagedExtensionUpdates}from"./extension/managed-update-status.js";import{runExtensionMigrateAction}from"./extension/migrations.js";import{buildBundledInstallReceipt}from"./extension/install-receipts.js";import{buildExtensionInstallPlan}from"./extension/install-plan.js";import{inspectExtensionAuthorManifestAtPmRoot}from"./extension/author-manifest.js";import{resolveExtensionInstallSourceIdentity}from"./extension/source-resolution.js";import{captureExtensionInstallSnapshot,readOptionalMetadataFile,restoreExtensionInstallSnapshot}from"./extension/install-snapshot.js";const LIFECYCLE_ACTION_TARGETS=[["install","install","--install"],["uninstall","uninstall","--uninstall"],["explore","explore","--explore"],["list","explore","--explore"],["manage","manage","--manage"],["describe","describe","--describe"],["reload","reload","--reload"],["doctor","doctor","--doctor"],["catalog","catalog","--catalog"],["init","init","--init"],["scaffold","init","--scaffold"],["adopt","adopt","--adopt"],["adopt-all","adopt-all","--adopt-all"],["activate","activate","--activate"],["deactivate","deactivate","--deactivate"],["migrate","migrate","--migrate"]],LIFECYCLE_ACTION_FLAG_HINT=LIFECYCLE_ACTION_TARGETS.map(([,,flag])=>flag).filter((flag,index,flags)=>flags.indexOf(flag)===index).join(", "),LIFECYCLE_ACTION_FLAGS={install:"--install",uninstall:"--uninstall",explore:"--explore",manage:"--manage",describe:"--describe",reload:"--reload",doctor:"--doctor",catalog:"--catalog",adopt:"--adopt","adopt-all":"--adopt-all",activate:"--activate",deactivate:"--deactivate",migrate:"--migrate",init:"--init"},NATIVE_OUTPUT_MARKER="__pm_native_output",EXTENSION_POLICY_ROOT_LIST_FIELDS=["trusted_extensions","allowed_extensions","blocked_extensions","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"],EXTENSION_POLICY_OVERRIDE_LIST_FIELDS=["allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"],EXTENSION_POLICY_OVERRIDE_BOOLEAN_FIELDS=["disabled","require_trusted","require_provenance"],DEFAULT_EXTENSION_POLICY_DETAILS={mode:"off",trust_mode:"off",require_provenance:!1,trusted_extensions:[],default_sandbox_profile:"none",allowed_extensions:[],blocked_extensions:[],allowed_capabilities:[],blocked_capabilities:[],allowed_surfaces:[],blocked_surfaces:[],allowed_commands:[],blocked_commands:[],allowed_actions:[],blocked_actions:[],allowed_services:[],blocked_services:[],extension_overrides:[]},normalizePolicyRootLists=policy=>{const safePolicy=policy??DEFAULT_EXTENSION_POLICY_DETAILS,lists={};for(const field of EXTENSION_POLICY_ROOT_LIST_FIELDS)lists[field]=normalizeStringList(safePolicy[field]??[]);return lists},appendNonEmptyPolicyLists=(target,lists)=>{for(const field of EXTENSION_POLICY_OVERRIDE_LIST_FIELDS)lists[field].length>0&&(target[field]=lists[field]);return target},appendEnabledPolicyScalars=(target,override)=>{for(const field of EXTENSION_POLICY_OVERRIDE_BOOLEAN_FIELDS)override[field]===!0&&(target[field]=!0);return override.sandbox_profile&&(target.sandbox_profile=override.sandbox_profile),target},normalizePolicyOverrideLists=override=>{const lists={};for(const field of EXTENSION_POLICY_OVERRIDE_LIST_FIELDS)lists[field]=normalizeStringList(override[field]??[]);return lists},buildExtensionPolicyOverrideDetails=override=>{const name=typeof override.name=="string"?override.name.trim():"";return name.length===0?null:appendNonEmptyPolicyLists(appendEnabledPolicyScalars({name},override),normalizePolicyOverrideLists(override))},normalizeExtensionPolicyOverrides=overrides=>(overrides??[]).map(override=>buildExtensionPolicyOverrideDetails(override)).filter(override=>override!==null).sort((left,right)=>left.name.localeCompare(right.name)),buildExtensionPolicyDetails=policy=>{const safePolicy=Object.assign({},DEFAULT_EXTENSION_POLICY_DETAILS,policy??{}),rootLists=normalizePolicyRootLists(policy),overrides=normalizeExtensionPolicyOverrides(safePolicy.extension_overrides);return{mode:safePolicy.mode,trust_mode:safePolicy.trust_mode,require_provenance:safePolicy.require_provenance===!0,trusted_extensions:rootLists.trusted_extensions,default_sandbox_profile:safePolicy.default_sandbox_profile,allowed_extensions:rootLists.allowed_extensions,blocked_extensions:rootLists.blocked_extensions,allowed_capabilities:rootLists.allowed_capabilities,blocked_capabilities:rootLists.blocked_capabilities,allowed_surfaces:rootLists.allowed_surfaces,blocked_surfaces:rootLists.blocked_surfaces,allowed_commands:rootLists.allowed_commands,blocked_commands:rootLists.blocked_commands,allowed_actions:rootLists.allowed_actions,blocked_actions:rootLists.blocked_actions,allowed_services:rootLists.allowed_services,blocked_services:rootLists.blocked_services,extension_overrides:overrides}},resolveInstalledExtensionCandidate=async(installed,extensionTarget)=>{const lookupValues=[extensionTarget],bundledAliasManifestName=await resolveBundledAliasManifestName(extensionTarget);bundledAliasManifestName&&lookupValues.push(bundledAliasManifestName);const normalizedLookups=[...new Set(lookupValues.map(value=>normalizeExtensionNameForMatch(value)).filter(value=>value.length>0))];for(const lookup of normalizedLookups){const byName=installed.find(entry=>normalizeExtensionNameForMatch(entry.name)===lookup);if(byName)return byName;const byDirectory=installed.find(entry=>normalizeExtensionNameForMatch(entry.directory)===lookup);if(byDirectory)return byDirectory}},isExtensionEnabled=(settings,name)=>{const normalizedName=name.trim(),enabled=new Set(normalizeStringList(settings.extensions.enabled));return new Set(normalizeStringList(settings.extensions.disabled)).has(normalizedName)?!1:enabled.size===0?!0:enabled.has(normalizedName)},ensureActivated=(settings,name)=>{const normalizedName=name.trim(),enabled=new Set(normalizeStringList(settings.extensions.enabled)),disabled=new Set(normalizeStringList(settings.extensions.disabled)),previousEnabled=[...enabled],previousDisabled=[...disabled];return disabled.delete(normalizedName),enabled.size>0&&enabled.add(normalizedName),settings.extensions.enabled=[...enabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.disabled=[...disabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.enabled.join("\0")!==previousEnabled.join("\0")||settings.extensions.disabled.join("\0")!==previousDisabled.join("\0")},ensureDeactivated=(settings,name)=>{const normalizedName=name.trim(),enabled=new Set(normalizeStringList(settings.extensions.enabled)),disabled=new Set(normalizeStringList(settings.extensions.disabled)),previousEnabled=[...enabled],previousDisabled=[...disabled];return enabled.delete(normalizedName),disabled.add(normalizedName),settings.extensions.enabled=[...enabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.disabled=[...disabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.enabled.join("\0")!==previousEnabled.join("\0")||settings.extensions.disabled.join("\0")!==previousDisabled.join("\0")},clearExtensionState=(settings,name)=>{const normalizedName=name.trim(),enabled=new Set(normalizeStringList(settings.extensions.enabled)),disabled=new Set(normalizeStringList(settings.extensions.disabled)),previousEnabled=[...enabled],previousDisabled=[...disabled];return enabled.delete(normalizedName),disabled.delete(normalizedName),settings.extensions.enabled=[...enabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.disabled=[...disabled].sort((left,right)=>left.localeCompare(right)),settings.extensions.enabled.join("\0")!==previousEnabled.join("\0")||settings.extensions.disabled.join("\0")!==previousDisabled.join("\0")},suggestLifecycleActionTarget=target=>{const normalizedTarget=target.trim().toLowerCase(),maxDistance=Math.min(2,Math.max(1,Math.ceil(normalizedTarget.length/4))),nearest=LIFECYCLE_ACTION_TARGETS.map(([candidate,action,flag])=>({action,flag,distance:levenshteinDistanceWithinLimit(normalizedTarget,candidate,maxDistance)})).filter(entry=>entry.distance!==null).sort((left,right)=>left.distance-right.distance)[0];return nearest?{action:nearest.action,flag:nearest.flag}:null},buildUnknownLifecycleActionError=(target,options)=>{const noun=options.vocabulary==="package"?"package":"extension",suggestion=suggestLifecycleActionTarget(target);if(!suggestion)return new PmCliError(`One action flag is required. Use one of: ${LIFECYCLE_ACTION_FLAG_HINT}. Bare \`pm package\` and \`pm extension\` default to --explore.`,EXIT_CODE.USAGE);const command=`pm ${noun} ${suggestion.flag}`;return createUnknownSubcommandError({command_path:noun,display_name:`${noun} lifecycle`,token_kind:"action",token:target,allowed:Object.keys(IMPLICIT_EXTENSION_ACTIONS),retry_command:command,message_suffix:`. Did you mean "${suggestion.flag}"?`,fallback_candidates:[{source:"lifecycle_action",command,reason:`nearest lifecycle action for "${target}"`}]})},EXTENSION_ACTION_FLAG_SELECTORS=[["install","install"],["uninstall","uninstall"],["explore","explore"],["manage","manage"],["describe","describe"],["reload","reload"],["doctor","doctor"],["catalog","catalog"],["init","init"],["scaffold","init"],["adopt","adopt"],["adoptAll","adopt-all"],["activate","activate"],["deactivate","deactivate"],["migrate","migrate"]],IMPLICIT_EXTENSION_ACTIONS={doctor:"doctor",reload:"reload",catalog:"catalog",init:"init",scaffold:"init",explore:"explore",manage:"manage",migrate:"migrate",list:"explore","":"explore"},resolveImplicitActionFromTarget=normalizedTarget=>IMPLICIT_EXTENSION_ACTIONS[normalizedTarget]??null,resolveAction=(target,options)=>{const selected=[...new Set(EXTENSION_ACTION_FLAG_SELECTORS.filter(([flag])=>options[flag]===!0).map(([,mappedAction])=>mappedAction))];if(selected.length===0){if(target===void 0)return"explore";const implicitAction=resolveImplicitActionFromTarget(target.trim().toLowerCase());if(implicitAction)return implicitAction;throw buildUnknownLifecycleActionError(target,options)}if(selected.length>1)throw new PmCliError("Extension action flags are mutually exclusive.",EXIT_CODE.USAGE);return selected[0]},resolveScope=options=>{const projectLike=options.project===!0||options.local===!0,global2=options.global===!0;if(projectLike&&global2)throw new PmCliError('Options "--project/--local" and "--global" are mutually exclusive.',EXIT_CODE.USAGE);return global2?"global":"project"},EXTENSION_UPDATE_CHECK_RESOLVERS=[managedEntry=>managedEntry?null:{status:"skipped_unmanaged",reason:"extension_not_managed"},managedEntry=>managedEntry&&!["github","npm"].includes(managedEntry.source.kind)?{status:"skipped_non_github",reason:`managed_source_kind_${managedEntry.source.kind}`}:null,managedEntry=>{const updateError=typeof managedEntry?.update_error=="string"?managedEntry.update_error.trim():"";return updateError.length>0?{status:"failed",reason:updateError}:null},managedEntry=>{const entry=managedEntry;return(typeof entry.last_update_check_at=="string"?entry.last_update_check_at.trim():"").length===0?null:{status:"checked",reason:{true:"update_available",false:"up_to_date"}[String(entry.update_available)]??"checked_without_commit_baseline"}}],resolveUpdateCheckResolution=managedEntry=>{for(const resolve of EXTENSION_UPDATE_CHECK_RESOLVERS){const resolution=resolve(managedEntry);if(resolution)return resolution}return{status:"not_checked",reason:"no_update_check_recorded"}},buildInstalledExtensionSummary=(identity,scope,managedEntry,updateCheck)=>{const managed=managedEntry??{};return{name:identity.name,directory:identity.directory,version:identity.version,entry:identity.entry,scope,active:identity.enabled,enabled:identity.enabled,runtime_active:null,activation_status:"unknown",contributions:managed.contributions,managed:!!managedEntry,source:managed.source,update_available:managed.update_available,last_update_check_at:managed.last_update_check_at,last_update_remote_commit:managed.last_update_remote_commit,last_update_remote_version:managed.last_update_remote_version,update_error:managed.update_error,update_check_status:updateCheck.status,update_check_reason:updateCheck.reason}},buildMissingManifestInspection=(directoryName,scope,settings,managedEntry)=>{const managed=Object.assign({name:directoryName,manifest_version:"unknown",manifest_entry:"unknown"},managedEntry),enabled=managedEntry?isExtensionEnabled(settings,managedEntry.name):!1;return{warning:`extension_manifest_missing:${scope}:${directoryName}`,summary:buildInstalledExtensionSummary({name:managed.name,directory:directoryName,version:managed.manifest_version,entry:managed.manifest_entry,enabled},scope,managedEntry,resolveUpdateCheckResolution(managedEntry))}},inspectInstalledExtensionDirectory=async(extensionsRoot,directoryName,scope,settings,managedByName,managedByDirectory)=>{const extensionDirectory=path.join(extensionsRoot,directoryName),manifestPath=path.join(extensionDirectory,"manifest.json"),managedDirectoryEntry=managedByDirectory.get(normalizeExtensionNameForMatch(directoryName));if(!await pathExists(manifestPath))return buildMissingManifestInspection(directoryName,scope,settings,managedDirectoryEntry);const invalidJson=Symbol("invalid-extension-manifest-json"),rawManifest=await fs.readFile(manifestPath,"utf8").then(contents=>JSON.parse(contents)).catch(()=>invalidJson);if(rawManifest===invalidJson)return{warning:`extension_manifest_invalid_json:${scope}:${directoryName}`};const manifest=parseExtensionManifest(rawManifest);if(!manifest)return{warning:`extension_manifest_invalid:${scope}:${directoryName}`};const managedEntry=managedByName.get(normalizeExtensionNameForMatch(manifest.name))??managedByDirectory.get(normalizeExtensionNameForMatch(directoryName));return{summary:buildInstalledExtensionSummary({name:manifest.name,directory:directoryName,version:manifest.version,entry:manifest.entry,enabled:isExtensionEnabled(settings,manifest.name)},scope,managedEntry,resolveUpdateCheckResolution(managedEntry))}},listInstalledExtensions=async(extensionsRoot,scope,settings,state)=>{if(!await pathExists(extensionsRoot))return{extensions:[],warnings:[]};const directories=(await fs.readdir(extensionsRoot,{withFileTypes:!0})).filter(entry=>entry.isDirectory()).map(entry=>entry.name).sort((left,right)=>left.localeCompare(right)),managedByName=new Map(state.entries.map(managedEntry=>[normalizeExtensionNameForMatch(managedEntry.name),managedEntry])),managedByDirectory=new Map(state.entries.map(managedEntry=>[normalizeExtensionNameForMatch(managedEntry.directory),managedEntry])),warnings=[],summaries=[];for(const directoryName of directories){const inspected=await inspectInstalledExtensionDirectory(extensionsRoot,directoryName,scope,settings,managedByName,managedByDirectory);inspected.warning&&warnings.push(inspected.warning),inspected.summary&&summaries.push(inspected.summary)}return{extensions:summaries.sort((left,right)=>left.name.localeCompare(right.name)),warnings:warnings.sort((left,right)=>left.localeCompare(right))}},extensionRuntimeProbeQueue=createSerialQueue(),resolveCommandDiscoveryPackageName=(extensionName,source)=>[source.package,source.kind==="builtin"?source.name:void 0].find(candidate=>candidate?.trim())?.trim()??extensionName,buildInstallCommandDiscovery=(extensionName,source,commandSummary,activationFailure)=>{const helpCommands=commandSummary.command_paths.map(commandPath=>`pm ${commandPath} --help`),sdkDependencyMissing=activationFailure?.error.toLowerCase().includes("@unbrained/pm-cli")===!0,nextSteps=commandSummary.command_paths.length>0?[...helpCommands]:["Run pm package doctor --project --detail deep if expected package commands are missing."];return sdkDependencyMissing&&nextSteps.unshift("Install @unbrained/pm-cli in the target workspace so declarative package runtime imports resolve, then reinstall the package."),{package_name:resolveCommandDiscoveryPackageName(extensionName,source),extension_name:extensionName,command_paths:commandSummary.command_paths,action_paths:commandSummary.action_paths,help_commands:helpCommands,next_steps:nextSteps,...sdkDependencyMissing?{sdk_dependency_status:"missing"}:{}}},summarizeActivationFailureForDiagnostics=failure=>{const trace=failure.trace,summary={layer:failure.layer,name:failure.name,entry_path:failure.entry_path,error:failure.error};return trace&&(summary.trace=Object.fromEntries(Object.entries(trace).filter(([,value])=>value!==void 0)),trace.missing_capability&&(summary.missing_capability=trace.missing_capability),trace.hint&&(summary.hint=trace.hint)),summary},collectActivationFailureDiagnostics=failures=>failures.map(failure=>summarizeActivationFailureForDiagnostics(failure)).sort((left,right)=>`${left.layer}:${left.name}`.localeCompare(`${right.layer}:${right.name}`)),findActivationFailureByName=(extensionName,failures,layer)=>{const normalizedName=normalizeExtensionNameForMatch(extensionName);return failures.find(failure=>(layer===void 0||failure.layer===layer)&&normalizeExtensionNameForMatch(failure.name)===normalizedName)},resolveInstallRuntimeActivationStatus=(extensionName,scope,runtimeInstalled,installActivationFailure)=>runtimeInstalled.find(entry=>entry.scope===scope&&normalizeExtensionNameForMatch(entry.name)===normalizeExtensionNameForMatch(extensionName))?.activation_status??(installActivationFailure?"failed":"unknown"),probeRuntimeCommandPathsForInstall=(pmRoot,parent,settings,refreshedInstalled,global2)=>extensionRuntimeProbeQueue.enqueue(async()=>{const originalPackageRoot=process.env.PM_CLI_PACKAGE_ROOT,snapshotRoot=await fs.mkdtemp(path.join(parent,".pm-module-graph-"));process.env.PM_CLI_PACKAGE_ROOT=resolvePmPackageRootFromModule(import.meta.url,["../.."]);try{const loadResult=await loadExtensions({pmRoot,settings,cwd:process.cwd(),noExtensions:global2.noExtensions===!0,reload_token:nextExtensionReloadToken(),cache_bust:!0,module_graph_snapshot_root:snapshotRoot}),activationResult=await activateExtensions({...loadResult}),runtimeFailures=[...loadResult.failed.map(failure=>({layer:failure.layer,name:failure.name,entry_path:failure.entry_path,error:failure.error})),...collectActivationFailureDiagnostics(activationResult.failed)],contributionInventories=Object.fromEntries(loadResult.loaded.map(extension=>[normalizeExtensionNameForMatch(extension.name),createExtensionContributionInventory(describeExtensionActivation(activationResult,{extensionName:extension.name}))]));return{installed:applyDoctorRuntimeActivationState(refreshedInstalled,loadResult,activationResult),warnings:[...loadResult.warnings,...activationResult.warnings],activation_failures:runtimeFailures,extensions_disabled:loadResult.disabled_by_flag,item_type_registrations:activationResult.registrations.item_types,contribution_inventories:contributionInventories}}finally{await fs.rm(snapshotRoot,{recursive:!0,force:!0}),originalPackageRoot===void 0?delete process.env.PM_CLI_PACKAGE_ROOT:process.env.PM_CLI_PACKAGE_ROOT=originalPackageRoot}}),adoptUnmanagedExtensions=async(extensionsRoot,scope,installedExtensions,state)=>{const unmanagedCandidates=installedExtensions.filter(entry=>!entry.managed),sortedCandidates=[...unmanagedCandidates].sort((left,right)=>{const byName=left.name.localeCompare(right.name);return byName!==0?byName:left.directory.localeCompare(right.directory)});let nextState=state;const adoptedEntries=[];for(const candidate of sortedCandidates){const extensionDirectory=path.join(extensionsRoot,candidate.directory),validated=await validateExtensionDirectory(extensionDirectory),now=nowIso(),sourceRecord={kind:"local",input:candidate.name,location:extensionDirectory};nextState=upsertManagedEntry(nextState,{name:validated.manifest.name,directory:candidate.directory,scope,manifest_version:validated.manifest.version,manifest_entry:validated.manifest.entry,capabilities:[...validated.manifest.capabilities],contributions:validated.manifest.contributions,installed_at:now,updated_at:now,source:sourceRecord}),adoptedEntries.push({name:validated.manifest.name,directory:candidate.directory,version:validated.manifest.version,entry:validated.manifest.entry,source:sourceRecord})}return adoptedEntries.length>0&&await writeManagedExtensionState(extensionsRoot,nextState),{state:nextState,adopted_entries:adoptedEntries,unmanaged_candidates:sortedCandidates,already_managed_count:installedExtensions.length-unmanagedCandidates.length}},resolveExtensionRootsForScope=(scope,global2)=>{const pmRoot=resolvePmRoot(process.cwd(),global2.path),roots=resolveExtensionRoots(pmRoot,process.cwd()),settingsRoot=scope==="global"?resolveGlobalPmRoot(process.cwd()):pmRoot,selectedRoot=scope==="global"?roots.global:roots.project;return{pm_root:pmRoot,scope,settings_root:settingsRoot,selected_root:selectedRoot,roots}},resolveGithubOption=options=>{const values=[options.gh,options.github].filter(value=>typeof value=="string").map(value=>value.trim()).filter(Boolean),uniqueValues=[...new Set(values)];if(uniqueValues.length>1)throw new PmCliError('Options "--gh" and "--github" must match when both are provided.',EXIT_CODE.USAGE);return uniqueValues[0]},getLifecycleActionFlag=action=>LIFECYCLE_ACTION_FLAGS[action],throwMissingLifecycleTarget=(action,options)=>{const noun=options.vocabulary==="package"?"package":"extension",targetName=action==="install"?"source":"name",targetLabel=`${noun} ${targetName}`,actionFlag=getLifecycleActionFlag(action),commandTarget=`<${targetName}>`,command=`pm ${noun} ${actionFlag} ${commandTarget}`;throw new PmCliError(`Action "${action}" requires ${targetLabel} input.`,EXIT_CODE.USAGE,{code:"missing_lifecycle_target",required:`Provide a ${targetName} target for ${action}.`,examples:[`pm ${noun} ${action} ${commandTarget}`,command,`pm ${noun} --help`],recovery:{attempted_command:`pm ${noun} ${action}`,suggested_retry:command,fallback_candidates:[{source:"lifecycle_action",command,reason:`flag-form ${action} command with required ${targetName} target`}]}})},requireTarget=(target,action,options={})=>{const normalized=target?.trim();if(normalized)return normalized;if(action==="init")throw new PmCliError('Action "init" requires a scaffold target path (for example: pm package init ./my-package or pm extension init ./my-extension).',EXIT_CODE.USAGE);return throwMissingLifecycleTarget(action,options)},collectSchemaNarrowActivationDoctorWarnings=(loadResult,activationResult)=>{const schemaContributors=new Set([...activationResult.registrations.item_types.map(entry=>({entry,count:entry.types.length})),...activationResult.registrations.item_fields.map(entry=>({entry,count:entry.fields.length}))].filter(({count})=>count>0).map(({entry})=>`${entry.layer}:${normalizeExtensionNameForMatch(entry.name)}`));return loadResult.loaded.filter(extension=>(extension.activation?.commands??[]).length>0).filter(extension=>schemaContributors.has(`${extension.layer}:${normalizeExtensionNameForMatch(extension.name)}`)).map(extension=>`extension_schema_narrow_activation:${extension.layer}:${extension.name}`).filter((warning,index,warnings)=>warnings.indexOf(warning)===index).sort((left,right)=>left.localeCompare(right))},assertExtensionActionOptionScope=(action,options)=>{const invalidGuard=[{triggered:options.strictExit===!0||options.failOnWarn===!0,allowed:action==="doctor",message:"--strict-exit and --fail-on-warn are only valid with --doctor."},{triggered:options.trace===!0,allowed:action==="doctor",message:"--trace is only valid with --doctor."},{triggered:options.watch===!0,allowed:action==="reload",message:"--watch is only valid with --reload."},{triggered:options.runtimeProbe===!0,allowed:action==="manage",message:"--runtime-probe is only valid with --manage."},{triggered:options.fixManagedState===!0,allowed:action==="manage"||action==="doctor",message:"--fix-managed-state is only valid with --manage or --doctor."},{triggered:options.isolated===!0||options.ignoreGlobal===!0,allowed:action==="doctor",message:"--isolated and --ignore-global are only valid with --doctor."},{triggered:options.capability!==void 0,allowed:action==="init",message:"--capability is only valid with --init/--scaffold."},{triggered:options.declarative===!0,allowed:action==="init",message:"--declarative is only valid with --init/--scaffold."},{triggered:options.dryRun===!0,allowed:action==="migrate"||action==="install",message:"--dry-run is only valid with --migrate or --install."}].find(guard=>guard.triggered&&!guard.allowed);if(invalidGuard)throw new PmCliError(invalidGuard.message,EXIT_CODE.USAGE)},resolveNormalizedExtensionTarget=(target,action,options)=>{const normalizedInput=String(target??"").trim().toLowerCase(),explicitInitAction=[options.init,options.scaffold].includes(!0);return({doctor:["doctor"],reload:["reload"],catalog:["catalog"],init:explicitInitAction?[]:["init","scaffold"]}[action]??[]).includes(normalizedInput)?void 0:target},resolveExtensionResultRoots=ctx=>[ctx.action==="catalog",typeof ctx.options.fields=="string",String(ctx.options.fields).trim().length>0].every(Boolean)?{project:"project",global:"global",selected:ctx.scope,settings_root:"project"}:{project:ctx.resolvedRoots.roots.project,global:ctx.resolvedRoots.roots.global,selected:ctx.resolvedRoots.selected_root,settings_root:ctx.resolvedRoots.settings_root},buildExtensionActionResult=(ctx,details,ok)=>{const result={ok,action:ctx.action,scope:ctx.scope,roots:resolveExtensionResultRoots(ctx),warnings:[...new Set(ctx.warnings)].sort((left,right)=>left.localeCompare(right)),details};return ctx.action==="doctor"&&Object.defineProperty(result,NATIVE_OUTPUT_MARKER,{value:!0,enumerable:!1,configurable:!1}),result},runExtension=async(target,options,global2)=>{const action=resolveAction(target,options);assertExtensionActionOptionScope(action,options);const normalizedTarget=resolveNormalizedExtensionTarget(target,action,options),scope=resolveScope(options),resolvedRoots=resolveExtensionRootsForScope(scope,global2),actionContext={action,normalizedTarget,scope,resolvedRoots,warnings:[],options,global:global2},ctx={...actionContext,withResult:(details,ok=!0)=>buildExtensionActionResult(actionContext,details,ok)};return await dispatchExtensionAction(ctx)},buildExtensionScaffoldNextSteps=(scaffold,options)=>{const vocabulary=options.vocabulary??"extension",shellTargetPath=scaffold.target_path.replace(/\\/g,"/"),quotedShellTargetPath=quoteCommandArg(shellTargetPath),dependencySteps={package:`Install dependencies: cd ${quotedShellTargetPath}, then run "npm install"`,extension:`Install type-check dependencies: cd ${quotedShellTargetPath}, then run "npm install -D typescript @types/node @unbrained/pm-cli"`},validationSteps={package:`Validate the package: cd ${quotedShellTargetPath}, then run "npm run typecheck" and "npm test"`,extension:`Type-check the source (optional): cd ${quotedShellTargetPath}, then run "npx tsc --noEmit"`},declarativeGuidance=[];return[vocabulary==="package",options.declarative===!0].every(Boolean)&&declarativeGuidance.push("Ensure the target workspace can resolve @unbrained/pm-cli before installing this declarative package."),[dependencySteps[vocabulary],...declarativeGuidance,`Install the scaffold: ${renderPmCommand(vocabulary==="package"?["install","--project",shellTargetPath]:["extension","--install","--project",shellTargetPath])}`,`Smoke-test command path: pm ${scaffold.command_name}`,validationSteps[vocabulary],`Run diagnostics: ${vocabulary==="package"?"pm package doctor":"pm extension --doctor"} --project --detail summary`]},runExtensionInitAction=async ctx=>{const{action,normalizedTarget,options,withResult}=ctx;if([resolveGithubOption(options),options.ref].filter(value=>typeof value=="string").map(value=>value.trim()).filter(Boolean).length>0)throw new PmCliError('Action "init" does not accept --gh/--github/--ref options.',EXIT_CODE.USAGE);const scaffoldTarget=requireTarget(normalizedTarget,action,options),scaffold=await scaffoldExtensionProject(scaffoldTarget,options.vocabulary??"extension",options.capability,options.declarative===!0);return withResult({scaffolded:scaffold.created_directory||scaffold.files.some(entry=>entry.status==="created"),extension:{name:scaffold.extension_name,command:scaffold.command_name},capability:scaffold.capability,style:scaffold.style,target_path:scaffold.target_path,created_directory:scaffold.created_directory,files:scaffold.files,next_steps:buildExtensionScaffoldNextSteps(scaffold,options)})},runExtensionReloadAction=async ctx=>{const{normalizedTarget,resolvedRoots,warnings,options,global:global2,withResult}=ctx;if(normalizedTarget!==void 0)throw new PmCliError('Action "reload" does not accept a target argument.',EXIT_CODE.USAGE);const settings=await readSettings(resolvedRoots.settings_root),reloadToken=nextExtensionReloadToken(),reloaded=await loadExtensions({pmRoot:resolvedRoots.settings_root,settings,cwd:process.cwd(),noExtensions:global2.noExtensions,reload_token:reloadToken,cache_bust:!0});warnings.push(...reloaded.warnings);const activation=await activateExtensions(reloaded);warnings.push(...activation.warnings);const details={reload:{token:reloadToken,cache_bust:!0,watch:options.watch===!0},loaded_count:reloaded.loaded.length,failed_count:reloaded.failed.length,activated_count:Math.max(0,reloaded.loaded.length-activation.failed.length),activation_failed_count:activation.failed.length,loaded_extensions:reloaded.loaded.map(entry=>({name:entry.name,layer:entry.layer,version:entry.version})),failed_extensions:reloaded.failed.map(entry=>({name:entry.name,layer:entry.layer,error:entry.error})),activation_failures:activation.failed.map(entry=>({name:entry.name,layer:entry.layer,error:entry.error}))};return options.watch===!0&&warnings.push("extension_reload_watch_hint:watch_mode_requested_non_interactive_single_pass_only"),withResult(details)},runExtensionCatalogAction=async ctx=>{const{normalizedTarget,scope,options,global:global2,withResult}=ctx;if(typeof normalizedTarget=="string"&&normalizedTarget.length>0&&normalizedTarget!=="catalog")throw new PmCliError('Action "catalog" does not accept a package target.',EXIT_CODE.USAGE);return withResult(await buildBundledPackageCatalog(scope,global2,options))},buildBundledInstallManagedSource=(alias,packageName)=>({kind:"builtin",input:alias,location:alias,name:alias,...packageName===null?{}:{package:packageName}}),buildLocalInstallManagedSource=source=>({kind:"local",input:source.input,location:source.absolute_path}),buildNpmInstallManagedSource=(source,resolved)=>({kind:"npm",input:source.input,location:resolved.resolved_subpath??".",package:resolved.npm_package,version:resolved.npm_version}),buildGithubInstallManagedSource=(source,resolved)=>({kind:"github",input:source.input,location:resolved.resolved_subpath??source.subpath??".",repository:source.repository,owner:source.owner,repo:source.repo,ref:source.ref,subpath:resolved.resolved_subpath??source.subpath,commit:resolved.commit}),buildInstallManagedSource=(bundledAliasName,bundledPackageName,installSource,resolvedSource)=>bundledAliasName?buildBundledInstallManagedSource(bundledAliasName,bundledPackageName):installSource.kind==="local"?buildLocalInstallManagedSource(installSource):installSource.kind==="npm"?buildNpmInstallManagedSource(installSource,resolvedSource):buildGithubInstallManagedSource(installSource,resolvedSource),resolveManagedInstallTimestamps=(existing,manifestVersion,source,now)=>existing?existing.manifest_version!==manifestVersion?{installed_at:existing.installed_at,updated_at:now}:managedExtensionSourcesEquivalent(existing.source,source)?{installed_at:existing.installed_at,updated_at:existing.updated_at}:{installed_at:existing.installed_at,updated_at:now}:{installed_at:now,updated_at:now},persistExtensionInstall=async(ctx,input)=>{const{scope,resolvedRoots,warnings}=ctx,{validated,destinationDirectoryName}=input,settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const destinationDirectory=path.join(resolvedRoots.selected_root,destinationDirectoryName),destinationExists=await pathExists(destinationDirectory),installInPlace=await areDirectoriesEquivalent(validated.directory,destinationDirectory);await fs.mkdir(resolvedRoots.selected_root,{recursive:!0});const backupRoot=await fs.mkdtemp(path.join(resolvedRoots.selected_root,".pm-extension-install-backup-")),backupDirectory=path.join(backupRoot,"destination");try{const snapshot=await captureExtensionInstallSnapshot(resolvedRoots.selected_root,resolvedRoots.settings_root,destinationDirectory,destinationExists,backupDirectory),sourceRecord=buildInstallManagedSource(input.bundledAliasName,input.bundledPackageName,input.installSource,input.resolvedSource),existingManagedEntry=managedStateRead.state.entries.find(entry=>normalizeExtensionNameForMatch(entry.name)===normalizeExtensionNameForMatch(validated.manifest.name)),timestamps=resolveManagedInstallTimestamps(existingManagedEntry,validated.manifest.version,sourceRecord,nowIso()),managedState=upsertManagedEntry(managedStateRead.state,{name:validated.manifest.name,directory:destinationDirectoryName,scope,manifest_version:validated.manifest.version,manifest_entry:validated.manifest.entry,capabilities:[...validated.manifest.capabilities],contributions:validated.manifest.contributions,...timestamps,source:sourceRecord}),activationChanged=ensureActivated(settings,validated.manifest.name);try{installInPlace||await copyExtensionDirectoryForInstall(validated.directory,destinationDirectory),await ensureExtensionModuleTypeMarker(destinationDirectory),await ensureInstalledExtensionSdkLink(destinationDirectory),await writeManagedExtensionState(resolvedRoots.selected_root,managedState),activationChanged&&await writeSettings(resolvedRoots.settings_root,settings,"settings:write")}catch(error){try{await restoreExtensionInstallSnapshot(snapshot)}catch(rollbackError){throw new AggregateError([error,rollbackError],`Extension install failed: ${String(error)}; rollback failed: ${String(rollbackError)}`,{cause:rollbackError})}throw error}return{settings,managedState,sourceRecord,destinationDirectory,destinationExists,installInPlace,activationChanged}}finally{await fs.rm(backupRoot,{recursive:!0,force:!0}).catch(()=>{})}},scaffoldInstalledExtensionItemTypes=async(ctx,extensionName,registrations)=>{const definitions=registrations.filter(entry=>normalizeExtensionNameForMatch(entry.name)===normalizeExtensionNameForMatch(extensionName)).flatMap(entry=>entry.types.map(type=>({name:type.name,folder:type.folder})));return ctx.scope==="project"&&definitions.length>0&&await ensureTypeFolderScaffold(ctx.resolvedRoots.pm_root,definitions,ctx.warnings,"install:type-folder"),definitions},buildInstalledExtensionActivation=(ctx,extensionName,runtimeProbe,commandSummary,installedItemTypes)=>{const failure=findActivationFailureByName(extensionName,runtimeProbe.activation_failures,ctx.scope),status=resolveInstallRuntimeActivationStatus(extensionName,ctx.scope,runtimeProbe.installed,failure),activated=[!runtimeProbe.extensions_disabled,status==="ok"].every(Boolean);activated||ctx.warnings.push(`extension_install_activation_failed:${ctx.scope}:${extensionName}:${status}`);const healthByActivation={true:{status:"ok",blocking_failure_count:0},false:{status:"degraded",blocking_failure_count:1}};return{activated,status,failure,verification:{status:healthByActivation[String(activated)].status,target_pm_root:ctx.resolvedRoots.pm_root,activation_status:status,activated,registered_commands:commandSummary.command_paths,registered_actions:commandSummary.action_paths,registered_item_types:installedItemTypes,module_graph_verification:"fresh_in_topology_snapshot",health:healthByActivation[String(activated)]}}},performExtensionInstallUnderLock=async(ctx,input)=>{const{scope,resolvedRoots,warnings,global:global2,withResult}=ctx,{validated,destinationDirectoryName}=input,persisted=await persistExtensionInstall(ctx,input),refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,persisted.settings,persisted.managedState);warnings.push(...refreshedInstalled.warnings);const runtimeProbe=await probeRuntimeCommandPathsForInstall(resolvedRoots.pm_root,path.dirname(resolvedRoots.selected_root),persisted.settings,refreshedInstalled.extensions,global2);warnings.push(...runtimeProbe.warnings);const installedItemTypeDefinitions=await scaffoldInstalledExtensionItemTypes(ctx,validated.manifest.name,runtimeProbe.item_type_registrations),commandSummary=summarizeRuntimeCommandPathsForExtension(validated.manifest.name,runtimeProbe.installed),activation=buildInstalledExtensionActivation(ctx,validated.manifest.name,runtimeProbe,commandSummary,installedItemTypeDefinitions),contributionInventory=runtimeProbe.contribution_inventories[normalizeExtensionNameForMatch(validated.manifest.name)];return contributionInventory&&(persisted.managedState=await persistManagedContributionInventory(resolvedRoots.selected_root,persisted.managedState,validated.manifest.name,contributionInventory)),withResult({extension:{name:validated.manifest.name,version:validated.manifest.version,entry:validated.manifest.entry,capabilities:validated.manifest.capabilities,directory:destinationDirectoryName},source:persisted.sourceRecord,source_resolution:input.sourceResolution,...input.installPlan?{install_plan:input.installPlan}:{},destination_path:persisted.destinationDirectory,overwritten:[persisted.destinationExists,!persisted.installInPlace].every(Boolean),installed_in_place:persisted.installInPlace,activated:activation.activated,settings_changed:persisted.activationChanged,runtime_activation_status:activation.status,command_paths:commandSummary.command_paths,action_paths:commandSummary.action_paths,contributions:contributionInventory,command_discovery:buildInstallCommandDiscovery(validated.manifest.name,persisted.sourceRecord,commandSummary,activation.failure),verification:activation.verification,activation_diagnostics:{failed_count:runtimeProbe.activation_failures.length,failed:runtimeProbe.activation_failures,installed_extension_failed:activation.failure??null}},activation.activated)},runBundledExtensionInstallAll=async ctx=>{const{options,global:global2,warnings,withResult}=ctx;if(typeof options.ref=="string"&&options.ref.trim().length>0)throw new PmCliError('Action "install all" does not accept --ref.',EXIT_CODE.USAGE);const packages=[],installedSources=new Map;for(const alias of await listBundledPackageAliases()){const source=await resolveBundledExtensionAliasSource(alias),sourceKey=path.resolve(source);let result=installedSources.get(sourceKey);result===void 0&&(result=await runExtension(alias,{...options,install:!0},global2),installedSources.set(sourceKey,result)),packages.push({alias,result})}return warnings.push(...packages.flatMap(entry=>entry.result.warnings)),withResult(buildBundledInstallReceipt(packages,options.dryRun===!0),packages.every(entry=>entry.result.ok))},runSingleExtensionInstall=async(ctx,explicitSourceInput,githubOption)=>{const{resolvedRoots}=ctx,{bundledAliasName,bundledPackageName,installSource,sourceResolution}=await resolveExtensionInstallSourceIdentity(explicitSourceInput,githubOption,ctx.options.ref,(await readManagedExtensionState(resolvedRoots.selected_root)).state.entries);if(sourceResolution.ambiguous){const npmCandidate=sourceResolution.candidates.find(candidate=>candidate.kind==="npm");ctx.warnings.push(`extension_install_source_ambiguous:${explicitSourceInput}:builtin:${bundledAliasName}:npm:${npmCandidate.package}`)}const resolvedSource=await resolveInstallSource(installSource);try{const validated=await validateExtensionDirectory(resolvedSource.directory,{source_kind:installSource.kind,source_input:installSource.input,source_root:resolvedSource.source_root}),destinationDirectoryName=normalizeManagedDirectoryName(validated.manifest.name),installPlan=ctx.options.dryRun===!0||installSource.kind==="local"&&bundledAliasName===null?await buildExtensionInstallPlan(resolvedSource,path.join(resolvedRoots.selected_root,destinationDirectoryName),ctx.scope,ctx.options.copyPlan):void 0;return ctx.options.dryRun===!0?ctx.withResult({dry_run:!0,installed:!1,activated:!1,extension:{name:validated.manifest.name,version:validated.manifest.version},source_resolution:sourceResolution,install_plan:installPlan}):await withExtensionInstallLock(resolvedRoots.settings_root,destinationDirectoryName,()=>performExtensionInstallUnderLock(ctx,{validated,destinationDirectoryName,bundledAliasName,bundledPackageName,sourceResolution,installSource,resolvedSource,installPlan}))}finally{resolvedSource.cleanup&&await resolvedSource.cleanup()}},runExtensionInstallAction=async ctx=>{const githubOption=resolveGithubOption(ctx.options),explicitSourceInput=githubOption??requireTarget(ctx.normalizedTarget,ctx.action,ctx.options);return[githubOption===void 0,isBundledPackageInstallAllTarget(explicitSourceInput)].every(Boolean)?runBundledExtensionInstallAll(ctx):runSingleExtensionInstall(ctx,explicitSourceInput,githubOption)},runExtensionAdoptAllAction=async ctx=>{const{normalizedTarget,scope,resolvedRoots,warnings,options,withResult}=ctx;if(normalizedTarget!==void 0)throw new PmCliError('Action "adopt-all" does not accept a target argument.',EXIT_CODE.USAGE);if(resolveGithubOption(options)!==void 0||typeof options.ref=="string"&&options.ref.trim().length>0)throw new PmCliError('Action "adopt-all" does not accept --gh/--github/--ref options.',EXIT_CODE.USAGE);const settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const adoption=await adoptUnmanagedExtensions(resolvedRoots.selected_root,scope,installed.extensions,managedStateRead.state),refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,adoption.state);warnings.push(...refreshedInstalled.warnings);const triage=buildExtensionTriageSummary(scope,warnings,refreshedInstalled.extensions,options);warnings.push(...triage.warnings);const refreshedByIdentity=new Map(refreshedInstalled.extensions.map(entry=>[`${normalizeExtensionNameForMatch(entry.name)}:${normalizeExtensionNameForMatch(entry.directory)}`,entry])),refreshedByDirectory=new Map(refreshedInstalled.extensions.map(entry=>[normalizeExtensionNameForMatch(entry.directory),entry])),adoptedDetails=adoption.adopted_entries.map(entry=>{const normalizedDirectory=normalizeExtensionNameForMatch(entry.directory),refreshedEntry=refreshedByIdentity.get(`${normalizeExtensionNameForMatch(entry.name)}:${normalizedDirectory}`)??refreshedByDirectory.get(normalizedDirectory);return{...entry,...projectExtensionUpdateCheck(refreshedEntry)}});return withResult({adopted_all:adoptedDetails.length>0,adopted_count:adoptedDetails.length,already_managed_count:adoption.already_managed_count,extensions:adoptedDetails,triage,warning_codes:triage.warning_codes,update_health_partial:triage.update_health_partial,update_health_coverage:triage.update_health_coverage})},projectExtensionUpdateCheck=entry=>({update_check_status:entry?.update_check_status??null,update_check_reason:entry?.update_check_reason??null}),buildAdoptedExtensionSource=(githubOption,extensionTarget,extensionDirectory,ref)=>{if(githubOption===void 0)return{kind:"local",input:extensionTarget,location:extensionDirectory};const parsed=parseExtensionInstallSource(githubOption,{forceGithub:!0,ref});if(parsed.kind!=="github")throw new PmCliError(`Invalid GitHub shorthand "${githubOption}".`,EXIT_CODE.USAGE);return{kind:"github",input:parsed.input,location:parsed.subpath??".",repository:parsed.repository,owner:parsed.owner,repo:parsed.repo,ref:parsed.ref,subpath:parsed.subpath}},runExtensionAdoptAction=async ctx=>{const{action,normalizedTarget,scope,resolvedRoots,warnings,options,withResult}=ctx,extensionTarget=requireTarget(normalizedTarget,action,options),githubOption=resolveGithubOption(options),settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const candidate=await resolveInstalledExtensionCandidate(installed.extensions,extensionTarget);if(!candidate)throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`,EXIT_CODE.NOT_FOUND);if(candidate.managed)return withResult({adopted:!1,already_managed:!0,extension:{name:candidate.name,directory:candidate.directory}});const extensionDirectory=path.join(resolvedRoots.selected_root,candidate.directory),validated=await validateExtensionDirectory(extensionDirectory),now=nowIso(),sourceRecord=buildAdoptedExtensionSource(githubOption,extensionTarget,extensionDirectory,options.ref),managedState=upsertManagedEntry(managedStateRead.state,{name:validated.manifest.name,directory:candidate.directory,scope,manifest_version:validated.manifest.version,manifest_entry:validated.manifest.entry,capabilities:[...validated.manifest.capabilities],contributions:validated.manifest.contributions,installed_at:now,updated_at:now,source:sourceRecord});await writeManagedExtensionState(resolvedRoots.selected_root,managedState);const refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedState);warnings.push(...refreshedInstalled.warnings);const refreshedEntry=refreshedInstalled.extensions.find(entry=>normalizeExtensionNameForMatch(entry.name)===normalizeExtensionNameForMatch(validated.manifest.name))??refreshedInstalled.extensions.find(entry=>normalizeExtensionNameForMatch(entry.directory)===normalizeExtensionNameForMatch(candidate.directory));return withResult({adopted:!0,extension:{name:validated.manifest.name,directory:candidate.directory,version:validated.manifest.version,entry:validated.manifest.entry},source:sourceRecord,...projectExtensionUpdateCheck(refreshedEntry)})},resolveRequiredInstalledExtension=async ctx=>{const{action,normalizedTarget,scope,resolvedRoots,warnings,options}=ctx,extensionTarget=requireTarget(normalizedTarget,action,options),settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const candidate=await resolveInstalledExtensionCandidate(installed.extensions,extensionTarget);if(!candidate)throw new PmCliError(`Installed extension "${extensionTarget}" was not found in ${scope} scope.`,EXIT_CODE.NOT_FOUND);return{settings,managedStateRead,candidate}},runExtensionUninstallAction=async ctx=>{const{resolvedRoots,withResult}=ctx,{settings,managedStateRead,candidate}=await resolveRequiredInstalledExtension(ctx),destinationDirectory=path.join(resolvedRoots.selected_root,candidate.directory);await fs.rm(destinationDirectory,{recursive:!0,force:!0});const updatedState={...managedStateRead.state,updated_at:nowIso(),entries:managedStateRead.state.entries.filter(entry=>normalizeExtensionNameForMatch(entry.name)!==normalizeExtensionNameForMatch(candidate.name)&&normalizeExtensionNameForMatch(entry.directory)!==normalizeExtensionNameForMatch(candidate.directory))};await writeManagedExtensionState(resolvedRoots.selected_root,updatedState);const stateChanged=clearExtensionState(settings,candidate.name);return stateChanged&&await writeSettings(resolvedRoots.settings_root,settings,"settings:write"),withResult({removed:!0,extension:{name:candidate.name,directory:candidate.directory},destination_path:destinationDirectory,settings_changed:stateChanged})},runExtensionActivateDeactivateAction=async ctx=>{const{action,resolvedRoots,warnings,global:global2,withResult}=ctx,{settings,candidate}=await resolveRequiredInstalledExtension(ctx),settingsChanged=action==="activate"?ensureActivated(settings,candidate.name):ensureDeactivated(settings,candidate.name);settingsChanged&&await writeSettings(resolvedRoots.settings_root,settings,"settings:write");const activationFailure=action==="activate"?await probeRuntimeCommandPathsForInstall(resolvedRoots.pm_root,path.dirname(resolvedRoots.selected_root),settings,[candidate],global2).then(probe=>(warnings.push(...probe.warnings),findActivationFailureByName(candidate.name,probe.activation_failures,ctx.scope))):void 0;return activationFailure&&warnings.push(`extension_activate_failed:${ctx.scope}:${candidate.name}`),withResult({extension:{name:candidate.name,directory:candidate.directory},active:action==="activate"&&activationFailure===void 0,runtime_active:action==="activate"&&activationFailure===void 0,activation_failure:activationFailure??null,settings_changed:settingsChanged,settings:{enabled:[...settings.extensions.enabled],disabled:[...settings.extensions.disabled]}},activationFailure===void 0)},buildDoctorRemediation=(baseRemediation,loadFailureCount,activationFailureCount,vocabulary,managedStateFix,isolationHint)=>{const noun=vocabulary==="package"?"package":"extension",doctorAction={package:"doctor",extension:"--doctor"}[noun],adoptedCount=managedStateFix?.adopted_entries.length??0,conditionalEntries=[[isolationHint!==null,isolationHint??""],[loadFailureCount>0,`Run pm ${noun} explore --project and pm ${noun} explore --global to inspect load failures.`],[activationFailureCount>0,`Review activation failures in pm ${noun} ${doctorAction} --detail deep output.`],[adoptedCount>0,`Managed-state fix adopted ${adoptedCount} extension(s).`]];return[...new Set([...baseRemediation,...conditionalEntries.filter(([include])=>include).map(([,entry])=>entry)].map(entry=>entry.trim()).filter(entry=>entry.length>0))]},hasGlobalLayerDiagnostics=loadResult=>loadResult.loaded.some(entry=>entry.layer==="global")||loadResult.failed.some(entry=>entry.layer==="global")||loadResult.warnings.some(warning=>warning.includes(":global:")),buildDoctorIsolationHint=(scope,isolated,vocabulary,loadResult)=>{if(scope!=="project"||isolated||!hasGlobalLayerDiagnostics(loadResult))return null;const noun=vocabulary==="package"?"package":"extension";return`Global ${noun} registrations are included in project diagnostics. For hermetic ${noun} smoke tests, rerun pm ${noun} doctor --project --isolated --detail deep --trace, or set PM_GLOBAL_PATH to a temporary directory for the whole test process.`},resolveDoctorInvocationOptions=(target,scope,options)=>{if(String(target??"").trim().length>0)throw new PmCliError('Action "doctor" does not accept a target argument.',EXIT_CODE.USAGE);const isolated=[options.isolated,options.ignoreGlobal].includes(!0);if([isolated,scope==="global"].every(Boolean))throw new PmCliError("--isolated and --ignore-global are only valid with project-scope doctor diagnostics.",EXIT_CODE.USAGE);const detailMode=parseDoctorDetailMode(options.detail),includeTrace=options.trace===!0;if([includeTrace,detailMode!=="deep"].every(Boolean))throw new PmCliError("--trace requires --detail deep with --doctor.",EXIT_CODE.USAGE);return{isolated,detailMode,includeTrace}},applyDoctorManagedStateFix=async(ctx,installed,state)=>{if(ctx.options.fixManagedState!==!0)return{state,fix:null};const fix=await adoptUnmanagedExtensions(ctx.resolvedRoots.selected_root,ctx.scope,installed,state);return{state:fix.state,fix}},buildDoctorIsolationMetadata=(scope,isolated,vocabulary,loadResult)=>{const noun=vocabulary==="package"?"package":"extension";if(scope!=="project")return{isolated,global_extensions_included:!1,global_diagnostics_present:hasGlobalLayerDiagnostics(loadResult),rerun_command:null,pm_global_path_recipe:null};const isolatedCommand=`pm ${noun} doctor --project --isolated --detail deep --trace`;return{isolated,global_extensions_included:!isolated,global_diagnostics_present:hasGlobalLayerDiagnostics(loadResult),rerun_command:isolated?null:isolatedCommand,pm_global_path_recipe:`PM_GLOBAL_PATH=$(mktemp -d) pm ${noun} doctor --project --detail deep --trace`}},runExtensionDoctorAction=async ctx=>{const{normalizedTarget,scope,resolvedRoots,warnings,options,global:global2,withResult}=ctx,{isolated,detailMode,includeTrace}=resolveDoctorInvocationOptions(normalizedTarget,scope,options),settings=await readSettings(resolvedRoots.settings_root),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const{state:managedState,fix:managedStateFix}=await applyDoctorManagedStateFix(ctx,installed.extensions,managedStateRead.state),refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedState);warnings.push(...refreshedInstalled.warnings);const loadResult=await loadExtensions({pmRoot:resolvedRoots.pm_root,settings,cwd:process.cwd(),noExtensions:global2.noExtensions===!0,ignoreGlobalExtensions:isolated}),activationResult=await activateExtensions({...loadResult,loaded:loadResult.loaded}),authorManifest=await inspectExtensionAuthorManifestAtPmRoot(resolvedRoots.pm_root);warnings.push(...authorManifest.warnings,...loadResult.warnings),warnings.push(...classifyDoctorLoadFailureWarnings(loadResult.failed)),warnings.push(...activationResult.warnings),warnings.push(...classifyDoctorActivationFailureWarnings(activationResult.failed)),warnings.push(...classifyUnusedCapabilityWarnings(loadResult,activationResult)),warnings.push(...collectGlobalOutputOverrideDoctorWarnings(activationResult,loadResult)),warnings.push(...collectSchemaNarrowActivationDoctorWarnings(loadResult,activationResult)),warnings.push(...collectMcpCustomFieldCollisionDoctorWarnings(activationResult));const runtimeInstalledExtensions=applyDoctorRuntimeActivationState(refreshedInstalled.extensions,loadResult,activationResult),doctorConsistency=buildDoctorConsistencySummary(scope,runtimeInstalledExtensions,loadResult.loaded.map(entry=>({layer:entry.layer,name:entry.name})),loadResult.failed.map(entry=>({name:entry.name})),loadResult.disabled_by_flag);warnings.push(...doctorConsistency.warnings);const updateCheckWarnings=runtimeInstalledExtensions.filter(entry=>entry.update_check_status==="failed").map(entry=>`extension_update_check_failed:${entry.name}`);warnings.push(...updateCheckWarnings);const triage=buildExtensionTriageSummary(scope,warnings,runtimeInstalledExtensions,options);warnings.push(...triage.warnings);const normalizedWarnings=[...triage.warnings],policySummary={mode:loadResult.policy.mode,trust_mode:loadResult.policy.trust_mode,require_provenance:loadResult.policy.require_provenance,default_sandbox_profile:loadResult.policy.default_sandbox_profile,sandbox_enforcement:"advisory: sandbox_profile/permissions are declaration-based load gates, not runtime isolation (ADR pm-6ef3)",trusted_extensions_count:loadResult.policy.trusted_extensions.length,allowed_extensions_count:loadResult.policy.allowed_extensions.length,blocked_extensions_count:loadResult.policy.blocked_extensions.length,allowed_capabilities_count:loadResult.policy.allowed_capabilities.length,blocked_capabilities_count:loadResult.policy.blocked_capabilities.length,allowed_surfaces_count:loadResult.policy.allowed_surfaces.length,blocked_surfaces_count:loadResult.policy.blocked_surfaces.length,allowed_commands_count:loadResult.policy.allowed_commands.length,blocked_commands_count:loadResult.policy.blocked_commands.length,allowed_actions_count:loadResult.policy.allowed_actions.length,blocked_actions_count:loadResult.policy.blocked_actions.length,allowed_services_count:loadResult.policy.allowed_services.length,blocked_services_count:loadResult.policy.blocked_services.length,extension_override_count:loadResult.policy.extension_overrides.length},capabilityGuidance=collectUnknownCapabilityGuidance(normalizedWarnings),capabilityContract=buildCapabilityContractMetadata(),warningCodes=triage.warning_codes,isolationHint=buildDoctorIsolationHint(scope,isolated,options.vocabulary,loadResult),remediation=buildDoctorRemediation(triage.remediation,loadResult.failed.length,activationResult.failed.length,options.vocabulary,managedStateFix,isolationHint),isolation=buildDoctorIsolationMetadata(scope,isolated,options.vocabulary,loadResult),summary={status:triage.status,scope,warning_count:triage.warning_count,warning_codes:warningCodes,total_extensions:runtimeInstalledExtensions.length,managed_total:runtimeInstalledExtensions.filter(entry=>entry.managed).length,enabled_total:runtimeInstalledExtensions.filter(entry=>entry.enabled).length,active_total:runtimeInstalledExtensions.filter(entry=>entry.active).length,unmanaged_loaded_extension_count:triage.unmanaged_loaded_extension_count,unmanaged_action_required_extension_count:triage.unmanaged_action_required_extension_count,unmanaged_expected_extension_count:triage.unmanaged_expected_extension_count,runtime_active_total:runtimeInstalledExtensions.filter(entry=>entry.runtime_active===!0).length,activation_status_totals:{ok:runtimeInstalledExtensions.filter(entry=>entry.activation_status==="ok").length,failed:runtimeInstalledExtensions.filter(entry=>entry.activation_status==="failed").length,not_loaded:runtimeInstalledExtensions.filter(entry=>entry.activation_status==="not_loaded").length,unknown:runtimeInstalledExtensions.filter(entry=>entry.activation_status==="unknown").length},unknown_capability_count:capabilityGuidance.length,capability_contract_version:capabilityContract.version,update_available_total:triage.update_available_total,update_check_status_totals:triage.update_check_status_totals,update_health_coverage:triage.update_health_coverage,update_health_partial:triage.update_health_partial,update_check_failed_total:runtimeInstalledExtensions.filter(entry=>entry.update_check_status==="failed").length,load_failure_count:loadResult.failed.length,activation_failure_count:activationResult.failed.length,load_failures:summarizeExtensionFailures(loadResult.failed),activation_failures:summarizeExtensionFailures(activationResult.failed),blocking_failure_count:loadResult.failed.length+activationResult.failed.length,has_blocking_failures:loadResult.failed.length+activationResult.failed.length>0,consistency_warning_count:doctorConsistency.warnings.length,trace_enabled:includeTrace,isolation,policy:policySummary,remediation},managedStateFixSummary=managedStateFix?{requested:!0,applied:managedStateFix.adopted_entries.length>0,adopted_count:managedStateFix.adopted_entries.length,already_managed_count:managedStateFix.already_managed_count,adopted_extensions:managedStateFix.adopted_entries.map(entry=>entry.name)}:{requested:!1,applied:!1,adopted_count:0,already_managed_count:refreshedInstalled.extensions.filter(entry=>entry.managed).length,adopted_extensions:[]},details={mode:detailMode,summary,triage,trace_enabled:includeTrace,capability_contract:capabilityContract,capability_guidance:capabilityGuidance,managed_state_fix:managedStateFixSummary,author_manifest:authorManifest,isolation,policy:loadResult.policy};if(detailMode==="deep"){const activationFailedDetails=includeTrace?activationResult.failed:activationResult.failed.map(entry=>{const{trace:_trace,...rest}=entry;return rest});details.deep={warnings:normalizedWarnings,warning_codes:warningCodes,capability_contract:capabilityContract,capability_guidance:capabilityGuidance,trace_enabled:includeTrace,managed_state:{path:managedStateRead.path,count:managedState.entries.length,entries:managedState.entries},installed_extensions:runtimeInstalledExtensions,load:{roots:loadResult.roots,policy:loadResult.policy,warnings:loadResult.warnings,failed:loadResult.failed,loaded:loadResult.loaded.map(entry=>({layer:entry.layer,directory:entry.directory,name:entry.name,version:entry.version,entry:entry.entry,priority:entry.priority}))},activation:{failed:activationFailedDetails,warnings:activationResult.warnings,hook_counts:activationResult.hook_counts,registration_counts:activationResult.registration_counts,parser_override_count:activationResult.parser_override_count,preflight_override_count:activationResult.preflight_override_count,service_override_count:activationResult.service_override_count,renderer_override_count:activationResult.renderer_override_count},consistency:doctorConsistency.summary},includeTrace&&(details.deep.trace={activation_failures:activationResult.failed.filter(entry=>entry.trace!==void 0).map(entry=>({layer:entry.layer,name:entry.name,entry_path:entry.entry_path,error:entry.error,method:entry.trace.method,command:entry.trace.command,capability:entry.trace.capability,missing_capability:entry.trace.missing_capability,registration_index:entry.trace.registration_index,expected_schema:entry.trace.expected_schema,hint:entry.trace.hint,received:entry.trace.received}))})}return withResult(details)},runExtensionDescribeAction=async ctx=>{const{normalizedTarget,scope,resolvedRoots,warnings,options,global:global2,withResult}=ctx,settings=await readSettings(resolvedRoots.settings_root),loadResult=await loadExtensions({pmRoot:resolvedRoots.pm_root,settings,cwd:process.cwd(),noExtensions:global2.noExtensions===!0}),activationResult=await activateExtensions(loadResult);warnings.push(...loadResult.warnings),warnings.push(...activationResult.warnings);const describeResult=buildExtensionDescribeResult(normalizedTarget,loadResult,activationResult);if(normalizedTarget!==void 0&&describeResult.extensions.length===0){const noun=options.vocabulary==="package"?"package":"extension",loadedNames=[...new Set(loadResult.loaded.map(entry=>options.vocabulary==="package"&&typeof entry.source_package=="string"&&entry.source_package.trim().length>0?entry.source_package.trim():entry.name))].sort((left,right)=>left.localeCompare(right)),loadedHint=loadedNames.length>0?` Loaded ${noun} names: ${loadedNames.join(", ")}.`:"";throw new PmCliError(`No loaded ${noun} named "${normalizedTarget}" was found in ${scope} scope.${loadedHint} Run pm ${noun} explore to list discovered ${noun}s.`,EXIT_CODE.NOT_FOUND)}return withResult({target:describeResult.target,total:describeResult.total,extensions:describeResult.extensions,union:describeResult.union,command_ownership:describeResult.command_ownership})},prepareExploreManageState=async(ctx,installed,initialState)=>{let state=initialState,fix=null;return[ctx.action==="manage",ctx.options.fixManagedState===!0].every(Boolean)&&(fix=await adoptUnmanagedExtensions(ctx.resolvedRoots.selected_root,ctx.scope,installed,initialState),state=fix.state),ctx.action==="manage"&&(state=await refreshManagedExtensionUpdates(state,ctx.options.offline)),{state,fix}},probeExploreManageRuntime=async(ctx,settings,installed)=>{const loadResult=await loadExtensions({pmRoot:ctx.resolvedRoots.pm_root,settings,cwd:process.cwd(),noExtensions:ctx.global.noExtensions===!0}),activationResult=await activateExtensions({...loadResult,loaded:loadResult.loaded});return ctx.warnings.push(...loadResult.warnings,...activationResult.warnings),{installed:applyDoctorRuntimeActivationState(installed,loadResult,activationResult),failures:collectActivationFailureDiagnostics(activationResult.failed),summary:{requested:!0,executed:!0,reason:ctx.action==="explore"?"explore_defaults_to_runtime_probe":ctx.options.runtimeProbe===!0?"runtime_probe_requested":"manage_defaults_to_runtime_probe",load_failure_count:loadResult.failed.length,activation_failure_count:activationResult.failed.length,warning_count:[...new Set([...loadResult.warnings,...activationResult.warnings])].length,policy:loadResult.policy}}},projectExploreManageFix=(fix,installed)=>fix?{requested:!0,applied:fix.adopted_entries.length>0,adopted_count:fix.adopted_entries.length,adopted_extensions:fix.adopted_entries.map(entry=>entry.name),already_managed_count:fix.already_managed_count}:{requested:!1,applied:!1,adopted_count:0,adopted_extensions:[],already_managed_count:installed.filter(entry=>entry.managed).length},runExtensionExploreManageAction=async ctx=>{const{action,scope,resolvedRoots,warnings,options,withResult}=ctx,settings=await readSettings(resolvedRoots.settings_root),configuredPolicy=buildExtensionPolicyDetails(settings.extensions.policy),managedStateRead=await readManagedExtensionState(resolvedRoots.selected_root);warnings.push(...managedStateRead.warnings);const installed=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedStateRead.state);warnings.push(...installed.warnings);const{state:managedState,fix:managedStateFix}=await prepareExploreManageState(ctx,installed.extensions,managedStateRead.state),refreshedInstalled=await listInstalledExtensions(resolvedRoots.selected_root,scope,settings,managedState);if(warnings.push(...refreshedInstalled.warnings),action==="manage"&&options.offline===!0)for(const extension of refreshedInstalled.extensions)extension.managed&&["npm","github"].includes(extension.source.kind)&&(extension.update_check_reason="offline_requested");if(action==="manage"){const updateWarnings=refreshedInstalled.extensions.filter(entry=>entry.update_check_status==="failed").map(entry=>`extension_update_check_failed:${entry.name}`);warnings.push(...updateWarnings)}const runtimeProbe=await probeExploreManageRuntime(ctx,settings,refreshedInstalled.extensions),runtimeInstalledExtensions=runtimeProbe.installed,triage=buildExtensionTriageSummary(scope,warnings,runtimeInstalledExtensions,options);warnings.push(...triage.warnings);const details={total:runtimeInstalledExtensions.length,managed_total:runtimeInstalledExtensions.filter(entry=>entry.managed).length,enabled_total:runtimeInstalledExtensions.filter(entry=>entry.enabled).length,active_total:runtimeInstalledExtensions.filter(entry=>entry.active).length,extensions:runtimeInstalledExtensions,triage,policy:configuredPolicy};return runtimeProbe.failures!==void 0&&(details.activation_diagnostics={failed_count:runtimeProbe.failures.length,failed:runtimeProbe.failures}),action==="explore"&&(details.runtime_probe=runtimeProbe.summary),action==="manage"&&(details.runtime_probe=runtimeProbe.summary,details.managed_state_fix=projectExploreManageFix(managedStateFix,runtimeInstalledExtensions)),withResult(details)},EXTENSION_ACTION_HANDLERS={init:runExtensionInitAction,install:runExtensionInstallAction,uninstall:runExtensionUninstallAction,explore:runExtensionExploreManageAction,manage:runExtensionExploreManageAction,describe:runExtensionDescribeAction,reload:runExtensionReloadAction,doctor:runExtensionDoctorAction,catalog:runExtensionCatalogAction,adopt:runExtensionAdoptAction,"adopt-all":runExtensionAdoptAllAction,activate:runExtensionActivateDeactivateAction,deactivate:runExtensionActivateDeactivateAction,migrate:runExtensionMigrateAction},requiresExtensionStateLock=ctx=>[ctx.action==="uninstall",ctx.action==="adopt",ctx.action==="adopt-all",ctx.action==="activate",ctx.action==="deactivate",ctx.action==="migrate",[["doctor","manage"].includes(ctx.action),ctx.options.fixManagedState===!0].every(Boolean)].some(Boolean),dispatchExtensionAction=ctx=>requiresExtensionStateLock(ctx)?withExtensionInstallLock(ctx.resolvedRoots.settings_root,`${ctx.action}-state`,()=>EXTENSION_ACTION_HANDLERS[ctx.action](ctx)):EXTENSION_ACTION_HANDLERS[ctx.action](ctx),_testOnly={adoptUnmanagedExtensions,buildAdoptedExtensionSource,buildExtensionPolicyDetails,buildInstallCommandDiscovery,checkGithubUpdate,clearExtensionState,collectActivationFailureDiagnostics,findActivationFailureByName,resolveInstallRuntimeActivationStatus,collectGlobalOutputOverrideDoctorWarnings,collectMcpCustomFieldCollisionDoctorWarnings,collectSchemaNarrowActivationDoctorWarnings,copyExtensionDirectoryWithoutSelfNesting,isErrnoCode,isRetriableExtensionInstallCopyError,listInstalledExtensions,mapWithFixedConcurrency,projectExtensionUpdateCheck,readOptionalMetadataFile,requireTarget,resolveAction,resolveCommandDiscoveryPackageName,resolveGithubOption,resolveInstalledExtensionCandidate,resolveManagedInstallTimestamps,resolveScope,resolveUpdateCheckResolution,withExtensionInstallLock};export{_testOnly,copyExtensionDirectoryForInstall,parseExtensionInstallSource,parseExtensionManifest,readManagedExtensionState,resolveCanonicalExtensionInstallDestination,resolveManagedExtensionStatePath,runExtension,validateExtensionDirectory,writeManagedExtensionState};
2
2
  //# sourceMappingURL=extension.js.map