@unbrained/pm-cli 2026.10.30 → 2026.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/pm-user/references/ECOSYSTEM_PLANNING.md +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/AGENTS.md +3 -3
- package/CHANGELOG.md +41 -0
- package/README.md +1 -1
- package/dist/cli/commander-usage.js +2 -2
- package/dist/cli/error-guidance.d.ts +45 -5
- package/dist/cli/error-guidance.js +5 -3
- package/dist/cli/extension-command-help.d.ts +1 -0
- package/dist/cli/extension-command-help.js +2 -2
- package/dist/cli/main.d.ts +1 -5
- package/dist/cli/main.js +5 -5
- package/dist/cli/migration-gates.d.ts +1 -1
- package/dist/cli/migration-gates.js +1 -1
- package/dist/cli/preflight-warnings.d.ts +11 -0
- package/dist/cli/preflight-warnings.js +4 -0
- package/dist/cli/register-mutation.js +2 -2
- package/dist/cli/register-operations.d.ts +3 -3
- package/dist/cli/register-operations.js +1 -1
- package/dist/cli-bundle/bundle-manifest.json +1 -1
- package/dist/cli-bundle/chunks/chunk-2GK2IVU5.js +8 -0
- package/dist/cli-bundle/chunks/chunk-5KW4WUAK.js +6 -0
- package/dist/cli-bundle/chunks/chunk-5WVE7XBS.js +114 -0
- package/dist/cli-bundle/chunks/chunk-6PKWKVS6.js +8 -0
- package/dist/cli-bundle/chunks/chunk-E74BORFX.js +128 -0
- package/dist/cli-bundle/chunks/chunk-F3ECOBKA.js +2 -0
- package/dist/cli-bundle/chunks/chunk-ICT6E4IW.js +2 -0
- package/dist/cli-bundle/chunks/chunk-MP2DQJH2.js +3 -0
- package/dist/cli-bundle/chunks/{chunk-LWW4F4G2.js → chunk-MRUA2Z43.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UUQX3PFD.js → chunk-MTRIGD7M.js} +76 -76
- package/dist/cli-bundle/chunks/{chunk-S2U7ECUJ.js → chunk-N45IXPCA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-MVL27TAH.js → chunk-NILQ2ZMV.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-GRABKNFL.js → chunk-O56O7NIE.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-O6TFUV6M.js +31 -0
- package/dist/cli-bundle/chunks/{chunk-TH5KPAN4.js → chunk-SBVX5CMV.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Y6NC3X3E.js → chunk-TMPO4CTZ.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-TYERATXH.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-EHBGHX55.js → chunk-UEEG47TU.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-UUN3WNMQ.js +20 -0
- package/dist/cli-bundle/chunks/chunk-WFBYKDB2.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-RZQNFHXO.js → chunk-WX25MU4N.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-4BQD5SW2.js → chunk-Y7CKVU56.js} +30 -30
- package/dist/cli-bundle/chunks/{indexed-receipt-blobs-LHLE7PSG.js → indexed-receipt-blobs-KGMJVFH2.js} +2 -2
- package/dist/cli-bundle/chunks/item-transaction-Q5S5YLEJ.js +2 -0
- package/dist/cli-bundle/chunks/{mutation-admission-TRGAVS7N.js → mutation-admission-BOOCJPCU.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-BH4F6M7Z.js → register-list-query-23OX36Q3.js} +3 -3
- package/dist/cli-bundle/chunks/register-mutation-JPJ5YNDX.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-IGR7ERY5.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-QPWSVHFZ.js → register-setup-BMIFKZZP.js} +2 -2
- package/dist/cli-bundle/chunks/{settlement-hook-MN3Y7LVX.js → settlement-hook-YWSWFOZY.js} +2 -2
- package/dist/cli-bundle/chunks/{stage-RTB6RAAO.js → stage-ON7CYYPM.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-POJPJX64.js → chunk-2Y77HWIX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-SAT7IAEB.js → chunk-3NYWMUX3.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-3Z53POXU.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-5TWS5KOM.js +26 -0
- package/dist/cli-bundle/focused-chunks/chunk-5WCQFH6D.js +12 -0
- package/dist/cli-bundle/focused-chunks/{chunk-S23ZUASN.js → chunk-6GMYW42K.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-YQUZL2CK.js → chunk-6OKPYCLU.js} +5 -5
- package/dist/cli-bundle/focused-chunks/chunk-7WJDRZOR.js +22 -0
- package/dist/cli-bundle/focused-chunks/{chunk-3SRX77ES.js → chunk-AL7SOFUL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-CIQ6YWCW.js +26 -0
- package/dist/cli-bundle/focused-chunks/{chunk-RKPUQDWF.js → chunk-DFUTCKUF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RYEZSZJ7.js → chunk-GE755ODZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-JCR32IAO.js +91 -0
- package/dist/cli-bundle/focused-chunks/{chunk-BPE6JTKL.js → chunk-JLXGRDTG.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-LVA76N27.js +6 -0
- package/dist/cli-bundle/focused-chunks/{chunk-YU7QOYYV.js → chunk-M22TI7LP.js} +3 -3
- package/dist/cli-bundle/focused-chunks/chunk-PAT6QF63.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-VFWCSQAG.js → chunk-RPUDOJVB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-SXZM4PSS.js +44 -0
- package/dist/cli-bundle/focused-chunks/chunk-UQIBGLDR.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-RGQEJFXO.js → chunk-VFQAZLKO.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-BCIUAEWX.js → chunk-VS2ZFPXD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FRFNGMAK.js → chunk-WX2RVS2Y.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-Z7GIVH6B.js +3 -0
- package/dist/cli-bundle/focused-chunks/{indexed-receipt-blobs-VK2363JB.js → indexed-receipt-blobs-KHWT44EK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/item-transaction-7VLPA2SU.js +2 -0
- package/dist/cli-bundle/focused-chunks/{mutation-admission-7VUODEPJ.js → mutation-admission-2DH27R5Y.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{settlement-hook-OK6A7PG2.js → settlement-hook-SJV52ZTV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{stage-S5RP5SZH.js → stage-FYOBWQA7.js} +2 -2
- package/dist/cli-bundle/main.js +26 -22
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +4 -4
- package/dist/cli-bundle/sdk-core.js +1 -1
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +57 -57
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +11 -11
- package/dist/core/config/nested-settings.js +1 -1
- package/dist/core/extensions/extension-hook-runtime.js +1 -1
- package/dist/core/extensions/extension-types.d.ts +4 -0
- package/dist/core/extensions/extension-types.js +1 -1
- package/dist/core/extensions/loader.js +1 -1
- package/dist/core/lock/lock.js +4 -4
- package/dist/core/output/mutation-projection.js +1 -1
- package/dist/core/output/output.js +3 -3
- package/dist/core/schema/fields-file.js +1 -1
- package/dist/core/sentry/helpers.d.ts +6 -0
- package/dist/core/sentry/helpers.js +1 -1
- package/dist/core/sentry/instrument.d.ts +1 -1
- package/dist/core/sentry/instrument.js +1 -1
- package/dist/core/shared/constants.js +1 -1
- package/dist/core/shared/errors.d.ts +6 -0
- package/dist/core/shared/errors.js +1 -1
- package/dist/core/shared/output-unicode.d.ts +10 -0
- package/dist/core/shared/output-unicode.js +2 -0
- package/dist/core/store/settings-validator.d.ts +1 -0
- package/dist/core/store/settings-validator.js +1 -1
- package/dist/core/store/settings.js +1 -1
- package/dist/core/telemetry/policy.d.ts +8 -0
- package/dist/core/telemetry/policy.js +1 -1
- package/dist/core/telemetry/runtime.js +3 -3
- package/dist/sdk/agent/command-recovery.d.ts +15 -0
- package/dist/sdk/agent/command-recovery.js +1 -1
- package/dist/sdk/cli-bootstrap.js +1 -1
- package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +28 -0
- package/dist/sdk/cli-contracts/agent-output-contracts.js +2 -2
- package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
- package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +1 -1
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +1 -1
- package/dist/sdk/completion/fish.js +4 -4
- package/dist/sdk/completion/zsh.js +3 -3
- package/dist/sdk/config.d.ts +1 -0
- package/dist/sdk/config.js +1 -1
- package/dist/sdk/context-intent-contracts.d.ts +17 -0
- package/dist/sdk/context-intent-contracts.js +1 -1
- package/dist/sdk/core.d.ts +2 -1
- package/dist/sdk/core.js +1 -1
- package/dist/sdk/error-runtime.d.ts +9 -0
- package/dist/sdk/error-runtime.js +1 -1
- package/dist/sdk/errors.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/index.d.ts +3 -3
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/init-agent-guidance.js +2 -2
- package/dist/sdk/lifecycle/claim.d.ts +27 -0
- package/dist/sdk/lifecycle/claim.js +1 -1
- package/dist/sdk/lifecycle/close.js +1 -1
- package/dist/sdk/lifecycle/create.js +1 -1
- package/dist/sdk/lifecycle/mcp-actions.d.ts +1 -1
- package/dist/sdk/lifecycle/mcp-actions.js +1 -1
- package/dist/sdk/lifecycle/plan.d.ts +2 -3
- package/dist/sdk/lifecycle/plan.js +1 -1
- package/dist/sdk/lifecycle/repeated-terminal-state.d.ts +45 -0
- package/dist/sdk/lifecycle/repeated-terminal-state.js +2 -0
- package/dist/sdk/lifecycle/shared-unset-fields.d.ts +9 -0
- package/dist/sdk/lifecycle/shared-unset-fields.js +1 -1
- package/dist/sdk/lifecycle/task-composition.js +1 -1
- package/dist/sdk/lifecycle/update-many.d.ts +0 -1
- package/dist/sdk/lifecycle/update-many.js +1 -1
- package/dist/sdk/lifecycle/update.d.ts +29 -1
- package/dist/sdk/lifecycle/update.js +2 -2
- package/dist/sdk/output/list-envelope.d.ts +8 -0
- package/dist/sdk/output/list-envelope.js +1 -1
- package/dist/sdk/output/table-rows.d.ts +7 -1
- package/dist/sdk/output/table-rows.js +1 -1
- package/dist/sdk/output.d.ts +2 -1
- package/dist/sdk/output.js +2 -2
- package/dist/sdk/ownership-source.d.ts +18 -0
- package/dist/sdk/ownership-source.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/context.js +2 -2
- package/dist/sdk/query/get.d.ts +1 -1
- package/dist/sdk/query/get.js +1 -1
- package/dist/sdk/query/next-ranking-policy.d.ts +35 -0
- package/dist/sdk/query/next-ranking-policy.js +2 -0
- package/dist/sdk/query/next.d.ts +12 -2
- package/dist/sdk/query/next.js +2 -2
- package/dist/sdk/query/projection-contracts.d.ts +4 -0
- package/dist/sdk/query/projection-contracts.js +1 -1
- package/dist/sdk/read-output/surfaces.d.ts +27 -0
- package/dist/sdk/read-output/surfaces.js +2 -0
- package/dist/sdk/read-output-contracts.js +1 -1
- package/dist/sdk/runtime/actions.js +1 -1
- package/dist/sdk/runtime-input.js +1 -1
- package/dist/sdk/runtime-primitives.d.ts +1 -0
- package/dist/sdk/runtime-primitives.js +1 -1
- package/dist/sdk/runtime-public-contracts.d.ts +2 -0
- package/dist/sdk/runtime.d.ts +2 -2
- package/dist/sdk/runtime.js +1 -1
- package/dist/sdk/start-task-status.d.ts +1 -1
- package/dist/sdk/start-task-status.js +1 -1
- package/dist/sdk/test/execution-receipts.d.ts +25 -0
- package/dist/sdk/test/execution-receipts.js +2 -2
- package/dist/sdk/test/execution.d.ts +5 -0
- package/dist/sdk/test/execution.js +2 -2
- package/dist/types.d.ts +2 -0
- package/dist/types.js +1 -1
- package/docs/AGENT_GUIDE.md +4 -4
- package/docs/AGENT_OUTPUT_ENCODINGS.md +12 -0
- package/docs/AGENT_UX_CONTRACTS.md +2 -1
- package/docs/COMMANDS.md +59 -5
- package/docs/COMMAND_NAMESPACES.md +1 -1
- package/docs/CONFIGURATION.md +48 -1
- package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +26 -0
- package/docs/LIFECYCLE_COMMANDS.md +19 -4
- package/docs/PACKED_FIRST_RUN.md +2 -1
- package/docs/READ_OUTPUT_CONTRACTS.md +24 -6
- package/docs/SDK.md +82 -3
- package/docs/SDK_ACTION_CONFORMANCE.md +21 -0
- package/docs/TESTING.md +38 -2
- package/docs/agent-task-token-baseline.json +1 -1
- package/docs/agent-task-transcripts.json +1 -1
- package/marketplace.json +1 -1
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/extensions/calendar/index.ts +1 -0
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/package.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +1 -1
- package/plugins/pm-codex/plugin.json +1 -1
- package/runtime-dependencies.json +1 -1
- package/dist/cli-bundle/chunks/chunk-34MP7WKK.js +0 -6
- package/dist/cli-bundle/chunks/chunk-3KMYHYJV.js +0 -2
- package/dist/cli-bundle/chunks/chunk-42BHHNTL.js +0 -128
- package/dist/cli-bundle/chunks/chunk-I5O3XZOA.js +0 -2
- package/dist/cli-bundle/chunks/chunk-LEIVUGDH.js +0 -8
- package/dist/cli-bundle/chunks/chunk-OH7WPD42.js +0 -114
- package/dist/cli-bundle/chunks/chunk-OOD2A7AF.js +0 -20
- package/dist/cli-bundle/chunks/chunk-Q5V7P6NM.js +0 -2
- package/dist/cli-bundle/chunks/chunk-QLPFYBXN.js +0 -2
- package/dist/cli-bundle/chunks/chunk-SA5NYLPE.js +0 -8
- package/dist/cli-bundle/chunks/chunk-VHLAVTJN.js +0 -31
- package/dist/cli-bundle/chunks/chunk-XAOVJG52.js +0 -3
- package/dist/cli-bundle/chunks/chunk-XPQ4RTSF.js +0 -2
- package/dist/cli-bundle/chunks/item-transaction-WIOBZW4E.js +0 -2
- package/dist/cli-bundle/chunks/register-mutation-5V2NANIS.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-XSFRMUFX.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2V6NMNYN.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-ASHGXMX4.js +0 -3
- package/dist/cli-bundle/focused-chunks/chunk-CKBN2D42.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-I642DXOT.js +0 -22
- package/dist/cli-bundle/focused-chunks/chunk-K7DKG5HM.js +0 -91
- package/dist/cli-bundle/focused-chunks/chunk-NMQBXU7N.js +0 -44
- package/dist/cli-bundle/focused-chunks/chunk-PGM3ENGZ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-QFNV4JTA.js +0 -6
- package/dist/cli-bundle/focused-chunks/chunk-QVJCQMZY.js +0 -26
- package/dist/cli-bundle/focused-chunks/chunk-R2TPPPVU.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-VJVJ2ZX2.js +0 -2
- package/dist/cli-bundle/focused-chunks/item-transaction-ZFDKJIP7.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
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]="f4308e20-251e-52d4-81a4-044e910e87fa")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{lstat,realpath}from"node:fs/promises";import path from"node:path";import{validateSettings}from"./settings-validator.js";import{runActiveOnReadHooks,runActiveOnWriteHooks}from"../extensions/index.js";import{EXIT_CODE,GOVERNANCE_PRESET_DEFAULTS,SETTINGS_DEFAULTS}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{resolveAuthor}from"../shared/author.js";import{isFileAbsentError,readFileIfExists,readRegularFile,transactionPreviewNonRegularFileError}from"../fs/fs-utils.js";import{mutateWorkspaceJsonWithHistory}from"../history/workspace-history.js";import{reconcileSettingsSnapshot}from"./settings-concurrency.js";import{DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,filePathForSchemaSection,loadRuntimeSchemaFromOptionalFiles,normalizeRuntimeSchemaSettings}from"../schema/runtime-schema.js";import{getSettingsPath}from"./paths.js";import{orderObject,stableValueEquals}from"../shared/serialization.js";import{normalizeItemTypeDefinition}from"../item/item-type-definition.js";import{normalizeEstimateDefaultOverrides}from"../validate/estimate-defaults.js";import{clearSettingsReadCache,collectSettingsReadCacheSignatures,getSettingsReadCacheEntry,setSettingsReadCacheEntry,settingsReadCacheSignaturesEqual}from"./settings-read-cache.js";const configurationOnlySettingsRoots=new AsyncLocalStorage;async function runWithConfigurationOnlySettings(pmRoot,run,isEnabled=()=>!0){const roots=new Set([path.resolve(pmRoot)]);try{roots.add(await realpath(pmRoot))}catch{}return configurationOnlySettingsRoots.run([...configurationOnlySettingsRoots.getStore()??[],[roots,isEnabled]],run)}function isConfigurationOnlySettingsRead(pmRoot){const root=path.resolve(pmRoot);return configurationOnlySettingsRoots.getStore()?.some(([roots,isEnabled])=>roots.has(root)&&isEnabled())??!1}const SETTINGS_WRITE_OP="settings:write",SETTINGS_PERSIST_SOURCE_SYMBOL=Symbol("pm.settings.persist_source"),MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH=128,DUPLICATE_DETECTION_MODES=new Set(["off","advisory","strict"]);function resolveGovernanceKnobsFromPreset(preset){return structuredClone(GOVERNANCE_PRESET_DEFAULTS[preset])}function normalizeGovernancePreset(value){return value==="minimal"||value==="default"||value==="strict"||value==="custom"?value:SETTINGS_DEFAULTS.governance.preset}function withGovernanceExtras(base,governance){const createDefaultType=typeof governance.create_default_type=="string"?governance.create_default_type.trim():void 0;return createDefaultType&&createDefaultType.length>0&&(base.create_default_type=createDefaultType),(governance.workflow_enforcement==="off"||governance.workflow_enforcement==="warn"||governance.workflow_enforcement==="strict")&&(base.workflow_enforcement=governance.workflow_enforcement),governance.require_close_reason===!1&&(base.require_close_reason=!1),base.duplicate_detection_mode=governance.duplicate_detection_mode,base.duplicate_detection_threshold=governance.duplicate_detection_threshold,base.duplicate_detection_limit=governance.duplicate_detection_limit,base}function normalizeGovernanceForPersist(governance){return governance.preset==="custom"?withGovernanceExtras({preset:"custom",ownership_enforcement:governance.ownership_enforcement,create_mode_default:governance.create_mode_default,close_validation_default:governance.close_validation_default,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,force_required_for_stale_lock:governance.force_required_for_stale_lock},governance):withGovernanceExtras({preset:governance.preset},governance)}function resolveGovernanceExtras(rawGovernance){const createDefaultType=typeof rawGovernance.create_default_type=="string"?rawGovernance.create_default_type.trim():void 0,extras={};createDefaultType&&createDefaultType.length>0&&(extras.create_default_type=createDefaultType),(rawGovernance.workflow_enforcement==="off"||rawGovernance.workflow_enforcement==="warn"||rawGovernance.workflow_enforcement==="strict")&&(extras.workflow_enforcement=rawGovernance.workflow_enforcement),typeof rawGovernance.require_close_reason=="boolean"&&(extras.require_close_reason=rawGovernance.require_close_reason),DUPLICATE_DETECTION_MODES.has(String(rawGovernance.duplicate_detection_mode))&&(extras.duplicate_detection_mode=rawGovernance.duplicate_detection_mode);const threshold=rawGovernance.duplicate_detection_threshold;[typeof threshold=="number",Number.isFinite(threshold),Number(threshold)>=0,Number(threshold)<=1].every(Boolean)&&(extras.duplicate_detection_threshold=threshold);const limit=rawGovernance.duplicate_detection_limit;return[typeof limit=="number",Number.isSafeInteger(limit),Number(limit)>=0,Number(limit)<=20].every(Boolean)&&(extras.duplicate_detection_limit=limit),extras}function resolveGovernanceKnobs(settings){const rawGovernance=settings.governance??{},preset=normalizeGovernancePreset(rawGovernance.preset),extras=resolveGovernanceExtras(rawGovernance);if(preset==="custom"){const baseline2=resolveGovernanceKnobsFromPreset("default"),requireCloseReason2=extras.require_close_reason??baseline2.require_close_reason;return{preset,ownership_enforcement:rawGovernance.ownership_enforcement??baseline2.ownership_enforcement,create_mode_default:rawGovernance.create_mode_default??baseline2.create_mode_default,close_validation_default:rawGovernance.close_validation_default??baseline2.close_validation_default,parent_reference:rawGovernance.parent_reference??baseline2.parent_reference,metadata_profile:rawGovernance.metadata_profile??baseline2.metadata_profile,force_required_for_stale_lock:rawGovernance.force_required_for_stale_lock??baseline2.force_required_for_stale_lock,...extras,require_close_reason:requireCloseReason2,duplicate_detection_mode:extras.duplicate_detection_mode??baseline2.duplicate_detection_mode,duplicate_detection_threshold:extras.duplicate_detection_threshold??baseline2.duplicate_detection_threshold,duplicate_detection_limit:extras.duplicate_detection_limit??baseline2.duplicate_detection_limit}}const baseline=resolveGovernanceKnobsFromPreset(preset),requireCloseReason=extras.require_close_reason??baseline.require_close_reason;return{preset,...baseline,...extras,require_close_reason:requireCloseReason}}function cloneDefaults(){return structuredClone(SETTINGS_DEFAULTS)}function normalizeSearchMutationRefreshPolicy(value){return value==="cache_only"||value==="semantic_configured"||value==="semantic_auto"?value:SETTINGS_DEFAULTS.search.mutation_refresh_policy}function normalizeSearchDefaultMode(value){return value==="auto"||value==="keyword"||value==="semantic"||value==="hybrid"?value:"auto"}function normalizeSearchQueryExpansionEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.query_expansion.enabled}function normalizeSearchQueryExpansionProvider(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.query_expansion.provider:value.trim()}function normalizeSearchRerankEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.rerank.enabled}function normalizeSearchRerankModel(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.rerank.model:value.trim()}function normalizeSearchRerankTopK(value){return typeof value=="number"&&Number.isFinite(value)&&Number.isInteger(value)&&value>0?value:SETTINGS_DEFAULTS.search.rerank.top_k}function normalizeVectorStoreCollectionName(value){if(typeof value!="string")return SETTINGS_DEFAULTS.vector_store.collection_name;const truncated=value.trim().replaceAll(/[^a-zA-Z0-9_-]/g,"_").slice(0,MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH);return truncated.length>0?truncated:SETTINGS_DEFAULTS.vector_store.collection_name}function cloneOptionalArray(value){return{present:Array.isArray(value),values:Array.isArray(value)?structuredClone(value):[]}}function buildSettingsPersistSourceSnapshot(parsedSettings,runtimeSettings){const sourceSchema=parsedSettings.schema,sourceStatuses=cloneOptionalArray(sourceSchema?.statuses),sourceFields=cloneOptionalArray(sourceSchema?.fields),sourceTypeWorkflows=cloneOptionalArray(sourceSchema?.type_workflows);return{persisted_settings:structuredClone(parsedSettings),source_settings:structuredClone(parsedSettings),has_source_item_type_definitions:Array.isArray(parsedSettings.item_types?.definitions),source_item_type_definitions:normalizeItemTypeDefinitions(parsedSettings.item_types?.definitions),has_source_schema_statuses:sourceStatuses.present,source_schema_statuses:sourceStatuses.values,has_source_schema_fields:sourceFields.present,source_schema_fields:sourceFields.values,has_source_schema_type_workflows:sourceTypeWorkflows.present,source_schema_type_workflows:sourceTypeWorkflows.values,runtime_item_type_definitions:normalizeItemTypeDefinitions(runtimeSettings.item_types?.definitions),runtime_schema_statuses:structuredClone(runtimeSettings.schema.statuses),runtime_schema_fields:structuredClone(runtimeSettings.schema.fields),runtime_schema_type_workflows:structuredClone(runtimeSettings.schema.type_workflows??[])}}function attachSettingsPersistSourceSnapshot(settings,source){Object.defineProperty(settings,SETTINGS_PERSIST_SOURCE_SYMBOL,{value:source,writable:!0,configurable:!0,enumerable:!1})}function getSettingsPersistSourceSnapshot(settings){const candidate=settings[SETTINGS_PERSIST_SOURCE_SYMBOL];if(!(!candidate||typeof candidate!="object"))return candidate}function persistSelectedItemFormat(settings){const source=getSettingsPersistSourceSnapshot(settings);if(source){const detachedSource=structuredClone(source);detachedSource.source_settings.item_format=settings.item_format,attachSettingsPersistSourceSnapshot(settings,detachedSource)}}function cloneSettingsReadResult(result){const clonedSettings=structuredClone(result.settings),persistSource=getSettingsPersistSourceSnapshot(result.settings);return persistSource&&attachSettingsPersistSourceSnapshot(clonedSettings,persistSource),{settings:clonedSettings,metadata:{has_explicit_item_format:result.metadata.has_explicit_item_format},warnings:[...result.warnings]}}function resolveSettingsReadTrackedPaths(pmRoot,schema,settingsPath){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);return[settingsPath,filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types),filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses),filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields),filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows)]}async function cacheSettingsReadResult(pmRoot,trackedPaths,result){const signatures=await collectSettingsReadCacheSignatures(trackedPaths);setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures,value:cloneSettingsReadResult(result)})}async function cacheSettingsReadResultSafe(pmRoot,trackedPaths,result){try{await cacheSettingsReadResult(pmRoot,trackedPaths,result)}catch{clearSettingsReadCache(pmRoot)}}function findSettingsReadCacheSignature(signatures,targetPath){return signatures.find(signature=>signature.path===targetPath)}function selectedSettingsReadCacheSignaturesEqual(before,after,targetPaths){for(const targetPath of targetPaths){const beforeSignature=findSettingsReadCacheSignature(before,targetPath),afterSignature=findSettingsReadCacheSignature(after,targetPath);if(!beforeSignature||!afterSignature||!settingsReadCacheSignaturesEqual([beforeSignature],[afterSignature]))return!1}return!0}async function cacheSettingsReadResultIfStable(pmRoot,trackedPaths,result,stableSignatures,stablePaths){try{const currentSignatures=await collectSettingsReadCacheSignatures(trackedPaths);if(!selectedSettingsReadCacheSignaturesEqual(stableSignatures,currentSignatures,stablePaths)){clearSettingsReadCache(pmRoot);return}setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:currentSignatures,value:cloneSettingsReadResult(result)})}catch{clearSettingsReadCache(pmRoot)}}function resolvePersistedFileBackedSchemaSections(settings,source){const normalizedSchema=normalizeRuntimeSchemaSettings(settings.schema),currentItemTypeDefinitions=normalizeItemTypeDefinitions(settings.item_types?.definitions);if(!source)return{item_type_definitions:currentItemTypeDefinitions,schema_statuses:normalizedSchema.statuses,schema_fields:normalizedSchema.fields,schema_type_workflows:normalizedSchema.type_workflows};const currentTypeWorkflows=normalizedSchema.type_workflows??[],itemTypeDefinitionsUnchanged=stableValueEquals(currentItemTypeDefinitions,source.runtime_item_type_definitions),schemaStatusesUnchanged=stableValueEquals(normalizedSchema.statuses,source.runtime_schema_statuses),schemaFieldsUnchanged=stableValueEquals(normalizedSchema.fields,source.runtime_schema_fields),schemaTypeWorkflowsUnchanged=stableValueEquals(currentTypeWorkflows,source.runtime_schema_type_workflows);return{item_type_definitions:itemTypeDefinitionsUnchanged?source.has_source_item_type_definitions?normalizeItemTypeDefinitions(source.source_item_type_definitions):[]:currentItemTypeDefinitions,schema_statuses:schemaStatusesUnchanged?source.has_source_schema_statuses?structuredClone(source.source_schema_statuses):[]:normalizedSchema.statuses,schema_fields:schemaFieldsUnchanged?source.has_source_schema_fields?structuredClone(source.source_schema_fields):[]:normalizedSchema.fields,schema_type_workflows:schemaTypeWorkflowsUnchanged?source.has_source_schema_type_workflows?structuredClone(source.source_schema_type_workflows):void 0:normalizedSchema.type_workflows}}function buildFallbackSettingsReadResult(warning){return{settings:cloneDefaults(),metadata:{has_explicit_item_format:!1},warnings:warning?[warning]:[]}}function hasExplicitItemFormat(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return!1;const itemFormat=raw.item_format;return itemFormat==="toon"||itemFormat==="json_markdown"}function normalizeStringList(values){return[...new Set((values??[]).map(value=>value.trim()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeAgentGuidanceSettings(value){const defaults=SETTINGS_DEFAULTS.agent_guidance,templateVersion=value?.template_version;return{prompt_completed:value?.prompt_completed===!0,declined:value?.declined===!0,declined_at:typeof value?.declined_at=="string"?value.declined_at:defaults.declined_at,template_version:typeof templateVersion=="number"&&Number.isInteger(templateVersion)&&templateVersion>0?templateVersion:defaults.template_version,last_checked_files:normalizeStringList(value?.last_checked_files??defaults.last_checked_files)}}function normalizeLowerStringList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeExtensionPolicyMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.mode}function normalizeExtensionTrustMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.trust_mode}function normalizeExtensionSandboxProfile(value){return value==="none"||value==="restricted"||value==="strict"?value:SETTINGS_DEFAULTS.extensions.policy.default_sandbox_profile}function normalizeExtensionPolicyOverride(override){const name=override.name.trim().toLowerCase();if(name.length===0)return null;const normalized={name};override.disabled===!0&&(normalized.disabled=!0),override.require_trusted===!0&&(normalized.require_trusted=!0),override.require_provenance===!0&&(normalized.require_provenance=!0),override.sandbox_profile!==void 0&&(normalized.sandbox_profile=normalizeExtensionSandboxProfile(override.sandbox_profile));const allowedCapabilities=normalizeLowerStringList(override.allowed_capabilities),blockedCapabilities=normalizeLowerStringList(override.blocked_capabilities),allowedSurfaces=normalizeLowerStringList(override.allowed_surfaces),blockedSurfaces=normalizeLowerStringList(override.blocked_surfaces),allowedCommands=normalizeLowerStringList(override.allowed_commands),blockedCommands=normalizeLowerStringList(override.blocked_commands),allowedActions=normalizeLowerStringList(override.allowed_actions),blockedActions=normalizeLowerStringList(override.blocked_actions),allowedServices=normalizeLowerStringList(override.allowed_services),blockedServices=normalizeLowerStringList(override.blocked_services);return allowedCapabilities.length>0&&(normalized.allowed_capabilities=allowedCapabilities),blockedCapabilities.length>0&&(normalized.blocked_capabilities=blockedCapabilities),allowedSurfaces.length>0&&(normalized.allowed_surfaces=allowedSurfaces),blockedSurfaces.length>0&&(normalized.blocked_surfaces=blockedSurfaces),allowedCommands.length>0&&(normalized.allowed_commands=allowedCommands),blockedCommands.length>0&&(normalized.blocked_commands=blockedCommands),allowedActions.length>0&&(normalized.allowed_actions=allowedActions),blockedActions.length>0&&(normalized.blocked_actions=blockedActions),allowedServices.length>0&&(normalized.allowed_services=allowedServices),blockedServices.length>0&&(normalized.blocked_services=blockedServices),normalized}function normalizeExtensionPolicyOverrides(overrides){const dedupedByName=new Map;for(const override of overrides??[]){const normalized=normalizeExtensionPolicyOverride(override);normalized&&dedupedByName.set(normalized.name,normalized)}return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function normalizePmMaxVersionExceededModeValue(value){return value==="block"||value==="warn"?value:void 0}function normalizePmMaxVersionExceededModeSetting(value){if(typeof value=="string")return normalizePmMaxVersionExceededModeValue(value);if(typeof value=="object"&&value!==null&&!Array.isArray(value)){const global2=normalizePmMaxVersionExceededModeValue(value.global),project=normalizePmMaxVersionExceededModeValue(value.project);return global2===void 0&&project===void 0?void 0:{...global2!==void 0?{global:global2}:{},...project!==void 0?{project}:{}}}}function normalizeExtensionPolicyList(policy,key){return normalizeLowerStringList(policy?.[key]??SETTINGS_DEFAULTS.extensions.policy[key])}function normalizeExtensionPolicySettings(policy){const pmMaxVersionExceededMode=normalizePmMaxVersionExceededModeSetting(policy?.pm_max_version_exceeded_mode);return{mode:normalizeExtensionPolicyMode(policy?.mode),trust_mode:normalizeExtensionTrustMode(policy?.trust_mode),...pmMaxVersionExceededMode!==void 0?{pm_max_version_exceeded_mode:pmMaxVersionExceededMode}:{},require_provenance:policy?.require_provenance===!0,trusted_extensions:normalizeExtensionPolicyList(policy,"trusted_extensions"),default_sandbox_profile:normalizeExtensionSandboxProfile(policy?.default_sandbox_profile),allowed_extensions:normalizeExtensionPolicyList(policy,"allowed_extensions"),blocked_extensions:normalizeExtensionPolicyList(policy,"blocked_extensions"),allowed_capabilities:normalizeExtensionPolicyList(policy,"allowed_capabilities"),blocked_capabilities:normalizeExtensionPolicyList(policy,"blocked_capabilities"),allowed_surfaces:normalizeExtensionPolicyList(policy,"allowed_surfaces"),blocked_surfaces:normalizeExtensionPolicyList(policy,"blocked_surfaces"),allowed_commands:normalizeExtensionPolicyList(policy,"allowed_commands"),blocked_commands:normalizeExtensionPolicyList(policy,"blocked_commands"),allowed_actions:normalizeExtensionPolicyList(policy,"allowed_actions"),blocked_actions:normalizeExtensionPolicyList(policy,"blocked_actions"),allowed_services:normalizeExtensionPolicyList(policy,"allowed_services"),blocked_services:normalizeExtensionPolicyList(policy,"blocked_services"),extension_overrides:normalizeExtensionPolicyOverrides(policy?.extension_overrides??SETTINGS_DEFAULTS.extensions.policy.extension_overrides)}}function normalizeValidationMetadataRequiredFields(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase().replaceAll("-","_")))].filter(value=>value.length>0).sort((left,right)=>left.localeCompare(right)).filter(value=>["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"].includes(value))}function normalizeValidationPatternList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function valueOrDefault(value,fallback){return value===void 0?fallback:value}function recordOrEmpty(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:{}}function arrayOrEmpty(value){return Array.isArray(value)?value:[]}function buildValidationSettings(settings,defaults,governance){return{...defaults.validation,...settings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(settings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_stale_blocker_reason_patterns??defaults.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_blocked_reason_patterns??defaults.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_resolution_patterns??defaults.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_actual_result_patterns??defaults.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(settings.validation?.estimate_defaults_by_type)}}function buildTelemetrySettings(settings,defaults){return{enabled:settings.telemetry?.enabled??defaults.telemetry.enabled,first_run_prompt_completed:settings.telemetry?.first_run_prompt_completed??defaults.telemetry.first_run_prompt_completed,capture_level:settings.telemetry?.capture_level??defaults.telemetry.capture_level,endpoint:settings.telemetry?.endpoint??defaults.telemetry.endpoint,installation_id:settings.telemetry?.installation_id??defaults.telemetry.installation_id,retention_days:settings.telemetry?.retention_days??defaults.telemetry.retention_days}}function buildSearchSettings(settings,defaults){return{...defaults.search,...settings.search,default_mode:normalizeSearchDefaultMode(settings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(settings.search?.mutation_refresh_policy),query_expansion:{...defaults.search.query_expansion,...settings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(settings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(settings.search?.query_expansion?.provider)},rerank:{...defaults.search.rerank,...settings.search?.rerank,enabled:normalizeSearchRerankEnabled(settings.search?.rerank?.enabled),model:normalizeSearchRerankModel(settings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(settings.search?.rerank?.top_k)}}}function buildVectorStoreSettings(settings,defaults){return{adapter:settings.vector_store.adapter??defaults.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(settings.vector_store.collection_name),qdrant:{...defaults.vector_store.qdrant,...settings.vector_store.qdrant},lancedb:{...defaults.vector_store.lancedb,...settings.vector_store.lancedb}}}function normalizeSettingsItemFormat(settings,defaults){return settings.item_format==="json_markdown"?"toon":settings.item_format??defaults.item_format}function buildContextSettings(settings,defaults){return{default_depth:settings.context?.default_depth??defaults.context.default_depth,activity_limit:settings.context?.activity_limit??defaults.context.activity_limit,stale_threshold_days:settings.context?.stale_threshold_days??defaults.context.stale_threshold_days,sections:{...defaults.context.sections,...settings.context?.sections}}}function buildProviderSettings(settings,defaults){return{openai:{...defaults.providers.openai,...settings.providers.openai},ollama:{...defaults.providers.ollama,...settings.providers.ollama}}}function normalizeItemTypeDefinitions(definitions){const normalized=(definitions??[]).map(definition=>normalizeItemTypeDefinition(definition)).filter(definition=>definition!==null),dedupedByName=new Map;for(const definition of normalized)dedupedByName.set(definition.name.toLowerCase(),definition);return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function mergeSettings(settings){const defaults=cloneDefaults(),governance=resolveGovernanceKnobs({governance:settings.governance??{preset:"default"}});return{...defaults,...settings,item_format:normalizeSettingsItemFormat(settings,defaults),locks:{...defaults.locks,...settings.locks},ids:{...defaults.ids,...settings.ids},agent_identity:structuredClone(settings.agent_identity??defaults.agent_identity),mutation_guard:{...defaults.mutation_guard,...settings.mutation_guard},checkpoints:{...defaults.checkpoints,...settings.checkpoints},output:{...defaults.output,...settings.output},ux:{...defaults.ux,...settings.ux},history:{...defaults.history,...settings.history,compact_policy:{...defaults.history.compact_policy,...settings.history?.compact_policy}},validation:buildValidationSettings(settings,defaults,governance),governance,workflow:{definition_of_done:[...settings.workflow?.definition_of_done??defaults.workflow.definition_of_done]},testing:{record_results_to_items:settings.testing?.record_results_to_items??defaults.testing.record_results_to_items,allow_untrusted_linked_tests:settings.testing?.allow_untrusted_linked_tests??defaults.testing.allow_untrusted_linked_tests},telemetry:buildTelemetrySettings(settings,defaults),agent_guidance:normalizeAgentGuidanceSettings(settings.agent_guidance??defaults.agent_guidance),item_types:{definitions:normalizeItemTypeDefinitions(settings.item_types?.definitions)},schema:normalizeRuntimeSchemaSettings(settings.schema??defaults.schema),context:buildContextSettings(settings,defaults),extensions:{enabled:[...settings.extensions.enabled],disabled:[...settings.extensions.disabled],policy:normalizeExtensionPolicySettings(settings.extensions.policy??defaults.extensions.policy)},search:buildSearchSettings(settings,defaults),providers:buildProviderSettings(settings,defaults),vector_store:buildVectorStoreSettings(settings,defaults)}}function orderSerializedSettingsSections(ordered){ordered.agent_identity=orderObject(ordered.agent_identity,["probes_enabled","identity_vocabulary","harness_signals"]);const orderedAgentIdentity=ordered.agent_identity;Object.hasOwn(orderedAgentIdentity,"identity_vocabulary")&&(orderedAgentIdentity.identity_vocabulary=orderObject(recordOrEmpty(orderedAgentIdentity.identity_vocabulary),["version","aliases"])),ordered.agent_identity.harness_signals=arrayOrEmpty(ordered.agent_identity.harness_signals).map(entry=>orderObject(recordOrEmpty(entry),["harness","environment_keys","model_environment_keys","session_environment_keys","provenance_environment_keys","provenance_resolvers","provenance_unavailable_dimensions","argv_markers","client_names"])),ordered.locks=orderObject(ordered.locks,["ttl_seconds","wait_ms"]),ordered.ids=orderObject(ordered.ids,["token_length"]),ordered.mutation_guard=orderObject(ordered.mutation_guard,["require_attributed_author","secret_guard","stale_in_progress_hours"]),ordered.checkpoints=orderObject(ordered.checkpoints,["retention_days"]),ordered.output=orderObject(ordered.output,["default_format"]),ordered.ux=orderObject(ordered.ux,["deprecation_hints"]),ordered.history=orderObject(ordered.history,["missing_stream","compact_policy"]),ordered.validation=orderObject(ordered.validation,["sprint_release_format","parent_reference","metadata_profile","metadata_required_fields","lifecycle_stale_blocker_reason_patterns","lifecycle_closure_like_blocked_reason_patterns","lifecycle_closure_like_resolution_patterns","lifecycle_closure_like_actual_result_patterns","estimate_defaults_by_type"]),ordered.governance=orderObject(ordered.governance,["preset","ownership_enforcement","create_mode_default","close_validation_default","require_close_reason","parent_reference","metadata_profile","force_required_for_stale_lock","create_default_type","workflow_enforcement","duplicate_detection_mode","duplicate_detection_threshold","duplicate_detection_limit"]),ordered.workflow=orderObject(ordered.workflow,["definition_of_done"]),ordered.testing=orderObject(ordered.testing,["record_results_to_items","allow_untrusted_linked_tests"]),ordered.telemetry=orderObject(ordered.telemetry,["enabled","first_run_prompt_completed","capture_level","endpoint","installation_id","retention_days"]),ordered.agent_guidance=orderObject(ordered.agent_guidance,["prompt_completed","declined","declined_at","template_version","last_checked_files"]),ordered.item_types=orderObject(ordered.item_types,["definitions"]),ordered.schema=orderObject(ordered.schema,["version","files","statuses","fields","workflow","type_workflows","unknown_field_policy"]),ordered.schema.files=orderObject(recordOrEmpty(ordered.schema.files),["types","statuses","fields","workflows"]),ordered.schema.workflow=orderObject(recordOrEmpty(ordered.schema.workflow),["draft_status","open_status","in_progress_status","blocked_status","close_status","canceled_status"]),ordered.context=orderObject(ordered.context,["default_depth","activity_limit","stale_threshold_days","sections"]),ordered.context.sections=orderObject(recordOrEmpty(ordered.context.sections),["hierarchy","activity","progress","blockers","files","workload","staleness","tests"]),ordered.extensions=orderObject(ordered.extensions,["enabled","disabled","policy"]),ordered.extensions.policy=orderObject(recordOrEmpty(ordered.extensions.policy),["mode","trust_mode","pm_max_version_exceeded_mode","require_provenance","trusted_extensions","default_sandbox_profile","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"]),ordered.extensions.policy.extension_overrides=arrayOrEmpty(ordered.extensions.policy.extension_overrides).map(entry=>orderObject(recordOrEmpty(entry),["name","disabled","require_trusted","require_provenance","sandbox_profile","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"])),ordered.search=orderObject(ordered.search,["score_threshold","hybrid_semantic_weight","max_results","embedding_model","embedding_corpus_max_characters","embedding_batch_size","embedding_timeout_ms","scanner_max_batch_retries","provider","default_mode","mutation_refresh_policy","query_expansion","rerank"]),ordered.search.query_expansion=orderObject(recordOrEmpty(ordered.search.query_expansion),["enabled","provider"]),ordered.search.rerank=orderObject(recordOrEmpty(ordered.search.rerank),["enabled","model","top_k"]),ordered.providers=orderObject(ordered.providers,["openai","ollama"]),ordered.providers.openai=orderObject(recordOrEmpty(ordered.providers.openai),["base_url","api_key","model"]),ordered.providers.ollama=orderObject(recordOrEmpty(ordered.providers.ollama),["base_url","model"]),ordered.vector_store=orderObject(ordered.vector_store,["adapter","collection_name","qdrant","lancedb"]),ordered.vector_store.qdrant=orderObject(recordOrEmpty(ordered.vector_store.qdrant),["url","api_key"]),ordered.vector_store.lancedb=orderObject(recordOrEmpty(ordered.vector_store.lancedb),["path"])}function buildSerializeBaseSettings(settings){return{...settings,locks:valueOrDefault(settings.locks,SETTINGS_DEFAULTS.locks),ids:valueOrDefault(settings.ids,SETTINGS_DEFAULTS.ids),agent_identity:valueOrDefault(settings.agent_identity,SETTINGS_DEFAULTS.agent_identity),mutation_guard:valueOrDefault(settings.mutation_guard,SETTINGS_DEFAULTS.mutation_guard),checkpoints:valueOrDefault(settings.checkpoints,SETTINGS_DEFAULTS.checkpoints),output:valueOrDefault(settings.output,SETTINGS_DEFAULTS.output),ux:valueOrDefault(settings.ux,SETTINGS_DEFAULTS.ux),history:valueOrDefault(settings.history,SETTINGS_DEFAULTS.history),validation:valueOrDefault(settings.validation,SETTINGS_DEFAULTS.validation),workflow:valueOrDefault(settings.workflow,SETTINGS_DEFAULTS.workflow),testing:valueOrDefault(settings.testing,SETTINGS_DEFAULTS.testing),telemetry:valueOrDefault(settings.telemetry,SETTINGS_DEFAULTS.telemetry),agent_guidance:valueOrDefault(settings.agent_guidance,SETTINGS_DEFAULTS.agent_guidance),item_types:valueOrDefault(settings.item_types,SETTINGS_DEFAULTS.item_types),schema:valueOrDefault(settings.schema,SETTINGS_DEFAULTS.schema),context:valueOrDefault(settings.context,SETTINGS_DEFAULTS.context),extensions:valueOrDefault(settings.extensions,SETTINGS_DEFAULTS.extensions),search:valueOrDefault(settings.search,SETTINGS_DEFAULTS.search),providers:valueOrDefault(settings.providers,SETTINGS_DEFAULTS.providers),vector_store:valueOrDefault(settings.vector_store,SETTINGS_DEFAULTS.vector_store)}}function buildSerializedValidationSettings(baseSettings,governance){return{...baseSettings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(baseSettings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_stale_blocker_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_blocked_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_resolution_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_actual_result_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(baseSettings.validation?.estimate_defaults_by_type)}}function buildSerializedSearchSettings(baseSettings){return{...SETTINGS_DEFAULTS.search,...baseSettings.search,default_mode:normalizeSearchDefaultMode(baseSettings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(baseSettings.search?.mutation_refresh_policy),query_expansion:{...SETTINGS_DEFAULTS.search.query_expansion,...baseSettings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(baseSettings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(baseSettings.search?.query_expansion?.provider)},rerank:{...SETTINGS_DEFAULTS.search.rerank,...baseSettings.search?.rerank,enabled:normalizeSearchRerankEnabled(baseSettings.search?.rerank?.enabled),model:normalizeSearchRerankModel(baseSettings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(baseSettings.search?.rerank?.top_k)}}}function buildSerializedContextSettings(baseSettings){return{default_depth:baseSettings.context?.default_depth??SETTINGS_DEFAULTS.context.default_depth,activity_limit:baseSettings.context?.activity_limit??SETTINGS_DEFAULTS.context.activity_limit,stale_threshold_days:baseSettings.context?.stale_threshold_days??SETTINGS_DEFAULTS.context.stale_threshold_days,sections:{...SETTINGS_DEFAULTS.context.sections,...baseSettings.context?.sections}}}function buildSerializedVectorStoreSettings(baseSettings){return{...baseSettings.vector_store,adapter:baseSettings.vector_store?.adapter??SETTINGS_DEFAULTS.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(baseSettings.vector_store?.collection_name),qdrant:{...baseSettings.vector_store?.qdrant},lancedb:{...baseSettings.vector_store?.lancedb}}}function buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections){return{...baseSettings,item_format:"toon",validation:buildSerializedValidationSettings(baseSettings,governance),governance,agent_guidance:normalizeAgentGuidanceSettings(baseSettings.agent_guidance),item_types:{definitions:persistedFileBackedSections.item_type_definitions},schema:{...normalizedSchema,statuses:persistedFileBackedSections.schema_statuses,fields:persistedFileBackedSections.schema_fields,type_workflows:persistedFileBackedSections.schema_type_workflows},search:buildSerializedSearchSettings(baseSettings),context:buildSerializedContextSettings(baseSettings),extensions:{enabled:normalizeStringList(baseSettings.extensions?.enabled),disabled:normalizeStringList(baseSettings.extensions?.disabled),policy:normalizeExtensionPolicySettings(baseSettings.extensions?.policy)},vector_store:buildSerializedVectorStoreSettings(baseSettings)}}function overlayPresentSettingsSource(target,source){for(const key of Object.keys(source)){const value=Reflect.get(source,key),existing=target[key];typeof value=="object"&&value!==null&&!Array.isArray(value)&&typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?overlayPresentSettingsSource(existing,value):target[key]=structuredClone(value)}}function applySettingsDelta(target,baseline,current){const keys=new Set([...Object.keys(baseline),...Object.keys(current)]);for(const key of keys){const before=baseline[key],after=current[key];if(!stableValueEquals(before,after)){if(after===void 0){delete target[key];continue}if(typeof before=="object"&&before!==null&&!Array.isArray(before)&&typeof after=="object"&&after!==null&&!Array.isArray(after)){const existing=target[key],nestedTarget=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?existing:{};applySettingsDelta(nestedTarget,before,after),Object.keys(nestedTarget).length>0?target[key]=nestedTarget:delete target[key];continue}target[key]=structuredClone(after)}}}const SETTINGS_TOP_LEVEL_KEY_ORDER=["version","id_prefix","ids","author_default","agent_identity","mutation_guard","item_format","locks","checkpoints","output","ux","history","validation","governance","workflow","testing","telemetry","agent_guidance","item_types","schema","context","extensions","search","providers","vector_store"];function buildOrderedSettingsForSerialization(settings,persistSource){const baseSettings=buildSerializeBaseSettings(settings),governance=resolveGovernanceKnobs(baseSettings),normalizedSchema=normalizeRuntimeSchemaSettings(baseSettings.schema),persistedFileBackedSections=resolvePersistedFileBackedSchemaSections(baseSettings,persistSource),normalizedSettings=buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections),ordered=orderObject({...normalizedSettings,governance:normalizeGovernanceForPersist(governance)},SETTINGS_TOP_LEVEL_KEY_ORDER);return orderSerializedSettingsSections(ordered),ordered}function serializeSettings(settings,options={}){const persistSource=options.source===void 0?options.persist_source:buildSettingsPersistSourceSnapshot(options.source.validated,mergeSettings(options.source.validated)),ordered=buildOrderedSettingsForSerialization(settings,persistSource);if(persistSource){const baselineSettings=mergeSettings(persistSource.source_settings);baselineSettings.item_types={definitions:structuredClone(persistSource.runtime_item_type_definitions)},baselineSettings.schema={...baselineSettings.schema,statuses:structuredClone(persistSource.runtime_schema_statuses),fields:structuredClone(persistSource.runtime_schema_fields),type_workflows:structuredClone(persistSource.runtime_schema_type_workflows)};const baseline=buildOrderedSettingsForSerialization(baselineSettings,persistSource);options.source!==void 0&&overlayPresentSettingsSource(baseline,options.source.validated);const sparse=structuredClone(options.source===void 0?persistSource.source_settings:options.source.raw);return applySettingsDelta(sparse,baseline,ordered),`${JSON.stringify(orderObject(sparse,SETTINGS_TOP_LEVEL_KEY_ORDER),null,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]="8d586108-d5b3-5c84-861a-cf532a979cdf")}catch{}})();import{AsyncLocalStorage}from"node:async_hooks";import{lstat,realpath}from"node:fs/promises";import path from"node:path";import{validateSettings}from"./settings-validator.js";import{runActiveOnReadHooks,runActiveOnWriteHooks}from"../extensions/index.js";import{EXIT_CODE,GOVERNANCE_PRESET_DEFAULTS,SETTINGS_DEFAULTS}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{resolveAuthor}from"../shared/author.js";import{isFileAbsentError,readFileIfExists,readRegularFile,transactionPreviewNonRegularFileError}from"../fs/fs-utils.js";import{mutateWorkspaceJsonWithHistory}from"../history/workspace-history.js";import{reconcileSettingsSnapshot}from"./settings-concurrency.js";import{DEFAULT_RUNTIME_SCHEMA_FILE_PATHS,filePathForSchemaSection,loadRuntimeSchemaFromOptionalFiles,normalizeRuntimeSchemaSettings}from"../schema/runtime-schema.js";import{getSettingsPath}from"./paths.js";import{orderObject,stableValueEquals}from"../shared/serialization.js";import{normalizeItemTypeDefinition}from"../item/item-type-definition.js";import{normalizeEstimateDefaultOverrides}from"../validate/estimate-defaults.js";import{clearSettingsReadCache,collectSettingsReadCacheSignatures,getSettingsReadCacheEntry,setSettingsReadCacheEntry,settingsReadCacheSignaturesEqual}from"./settings-read-cache.js";const configurationOnlySettingsRoots=new AsyncLocalStorage;async function runWithConfigurationOnlySettings(pmRoot,run,isEnabled=()=>!0){const roots=new Set([path.resolve(pmRoot)]);try{roots.add(await realpath(pmRoot))}catch{}return configurationOnlySettingsRoots.run([...configurationOnlySettingsRoots.getStore()??[],[roots,isEnabled]],run)}function isConfigurationOnlySettingsRead(pmRoot){const root=path.resolve(pmRoot);return configurationOnlySettingsRoots.getStore()?.some(([roots,isEnabled])=>roots.has(root)&&isEnabled())??!1}const SETTINGS_WRITE_OP="settings:write",SETTINGS_PERSIST_SOURCE_SYMBOL=Symbol("pm.settings.persist_source"),MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH=128,DUPLICATE_DETECTION_MODES=new Set(["off","advisory","strict"]);function resolveGovernanceKnobsFromPreset(preset){return structuredClone(GOVERNANCE_PRESET_DEFAULTS[preset])}function normalizeGovernancePreset(value){return value==="minimal"||value==="default"||value==="strict"||value==="custom"?value:SETTINGS_DEFAULTS.governance.preset}function withGovernanceExtras(base,governance){const createDefaultType=typeof governance.create_default_type=="string"?governance.create_default_type.trim():void 0;return createDefaultType&&createDefaultType.length>0&&(base.create_default_type=createDefaultType),(governance.workflow_enforcement==="off"||governance.workflow_enforcement==="warn"||governance.workflow_enforcement==="strict")&&(base.workflow_enforcement=governance.workflow_enforcement),governance.require_close_reason===!1&&(base.require_close_reason=!1),base.duplicate_detection_mode=governance.duplicate_detection_mode,base.duplicate_detection_threshold=governance.duplicate_detection_threshold,base.duplicate_detection_limit=governance.duplicate_detection_limit,base}function normalizeGovernanceForPersist(governance){return governance.preset==="custom"?withGovernanceExtras({preset:"custom",ownership_enforcement:governance.ownership_enforcement,create_mode_default:governance.create_mode_default,close_validation_default:governance.close_validation_default,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,force_required_for_stale_lock:governance.force_required_for_stale_lock},governance):withGovernanceExtras({preset:governance.preset},governance)}function resolveGovernanceExtras(rawGovernance){const createDefaultType=typeof rawGovernance.create_default_type=="string"?rawGovernance.create_default_type.trim():void 0,extras={};createDefaultType&&createDefaultType.length>0&&(extras.create_default_type=createDefaultType),(rawGovernance.workflow_enforcement==="off"||rawGovernance.workflow_enforcement==="warn"||rawGovernance.workflow_enforcement==="strict")&&(extras.workflow_enforcement=rawGovernance.workflow_enforcement),typeof rawGovernance.require_close_reason=="boolean"&&(extras.require_close_reason=rawGovernance.require_close_reason),DUPLICATE_DETECTION_MODES.has(String(rawGovernance.duplicate_detection_mode))&&(extras.duplicate_detection_mode=rawGovernance.duplicate_detection_mode);const threshold=rawGovernance.duplicate_detection_threshold;[typeof threshold=="number",Number.isFinite(threshold),Number(threshold)>=0,Number(threshold)<=1].every(Boolean)&&(extras.duplicate_detection_threshold=threshold);const limit=rawGovernance.duplicate_detection_limit;return[typeof limit=="number",Number.isSafeInteger(limit),Number(limit)>=0,Number(limit)<=20].every(Boolean)&&(extras.duplicate_detection_limit=limit),extras}function resolveGovernanceKnobs(settings){const rawGovernance=settings.governance??{},preset=normalizeGovernancePreset(rawGovernance.preset),extras=resolveGovernanceExtras(rawGovernance);if(preset==="custom"){const baseline2=resolveGovernanceKnobsFromPreset("default"),requireCloseReason2=extras.require_close_reason??baseline2.require_close_reason;return{preset,ownership_enforcement:rawGovernance.ownership_enforcement??baseline2.ownership_enforcement,create_mode_default:rawGovernance.create_mode_default??baseline2.create_mode_default,close_validation_default:rawGovernance.close_validation_default??baseline2.close_validation_default,parent_reference:rawGovernance.parent_reference??baseline2.parent_reference,metadata_profile:rawGovernance.metadata_profile??baseline2.metadata_profile,force_required_for_stale_lock:rawGovernance.force_required_for_stale_lock??baseline2.force_required_for_stale_lock,...extras,require_close_reason:requireCloseReason2,duplicate_detection_mode:extras.duplicate_detection_mode??baseline2.duplicate_detection_mode,duplicate_detection_threshold:extras.duplicate_detection_threshold??baseline2.duplicate_detection_threshold,duplicate_detection_limit:extras.duplicate_detection_limit??baseline2.duplicate_detection_limit}}const baseline=resolveGovernanceKnobsFromPreset(preset),requireCloseReason=extras.require_close_reason??baseline.require_close_reason;return{preset,...baseline,...extras,require_close_reason:requireCloseReason}}function cloneDefaults(){return structuredClone(SETTINGS_DEFAULTS)}function normalizeSearchMutationRefreshPolicy(value){return value==="cache_only"||value==="semantic_configured"||value==="semantic_auto"?value:SETTINGS_DEFAULTS.search.mutation_refresh_policy}function normalizeSearchDefaultMode(value){return value==="auto"||value==="keyword"||value==="semantic"||value==="hybrid"?value:"auto"}function normalizeSearchQueryExpansionEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.query_expansion.enabled}function normalizeSearchQueryExpansionProvider(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.query_expansion.provider:value.trim()}function normalizeSearchRerankEnabled(value){return typeof value=="boolean"?value:SETTINGS_DEFAULTS.search.rerank.enabled}function normalizeSearchRerankModel(value){return typeof value!="string"?SETTINGS_DEFAULTS.search.rerank.model:value.trim()}function normalizeSearchRerankTopK(value){return typeof value=="number"&&Number.isFinite(value)&&Number.isInteger(value)&&value>0?value:SETTINGS_DEFAULTS.search.rerank.top_k}function normalizeVectorStoreCollectionName(value){if(typeof value!="string")return SETTINGS_DEFAULTS.vector_store.collection_name;const truncated=value.trim().replaceAll(/[^a-zA-Z0-9_-]/g,"_").slice(0,MAX_VECTOR_STORE_COLLECTION_NAME_LENGTH);return truncated.length>0?truncated:SETTINGS_DEFAULTS.vector_store.collection_name}function cloneOptionalArray(value){return{present:Array.isArray(value),values:Array.isArray(value)?structuredClone(value):[]}}function buildSettingsPersistSourceSnapshot(parsedSettings,runtimeSettings){const sourceSchema=parsedSettings.schema,sourceStatuses=cloneOptionalArray(sourceSchema?.statuses),sourceFields=cloneOptionalArray(sourceSchema?.fields),sourceTypeWorkflows=cloneOptionalArray(sourceSchema?.type_workflows);return{persisted_settings:structuredClone(parsedSettings),source_settings:structuredClone(parsedSettings),has_source_item_type_definitions:Array.isArray(parsedSettings.item_types?.definitions),source_item_type_definitions:normalizeItemTypeDefinitions(parsedSettings.item_types?.definitions),has_source_schema_statuses:sourceStatuses.present,source_schema_statuses:sourceStatuses.values,has_source_schema_fields:sourceFields.present,source_schema_fields:sourceFields.values,has_source_schema_type_workflows:sourceTypeWorkflows.present,source_schema_type_workflows:sourceTypeWorkflows.values,runtime_item_type_definitions:normalizeItemTypeDefinitions(runtimeSettings.item_types?.definitions),runtime_schema_statuses:structuredClone(runtimeSettings.schema.statuses),runtime_schema_fields:structuredClone(runtimeSettings.schema.fields),runtime_schema_type_workflows:structuredClone(runtimeSettings.schema.type_workflows??[])}}function attachSettingsPersistSourceSnapshot(settings,source){Object.defineProperty(settings,SETTINGS_PERSIST_SOURCE_SYMBOL,{value:source,writable:!0,configurable:!0,enumerable:!1})}function getSettingsPersistSourceSnapshot(settings){const candidate=settings[SETTINGS_PERSIST_SOURCE_SYMBOL];if(!(!candidate||typeof candidate!="object"))return candidate}function persistSelectedItemFormat(settings){const source=getSettingsPersistSourceSnapshot(settings);if(source){const detachedSource=structuredClone(source);detachedSource.source_settings.item_format=settings.item_format,attachSettingsPersistSourceSnapshot(settings,detachedSource)}}function cloneSettingsReadResult(result){const clonedSettings=structuredClone(result.settings),persistSource=getSettingsPersistSourceSnapshot(result.settings);return persistSource&&attachSettingsPersistSourceSnapshot(clonedSettings,persistSource),{settings:clonedSettings,metadata:{has_explicit_item_format:result.metadata.has_explicit_item_format},warnings:[...result.warnings]}}function resolveSettingsReadTrackedPaths(pmRoot,schema,settingsPath){const normalizedSchema=normalizeRuntimeSchemaSettings(schema);return[settingsPath,filePathForSchemaSection(pmRoot,normalizedSchema.files.types,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.types),filePathForSchemaSection(pmRoot,normalizedSchema.files.statuses,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.statuses),filePathForSchemaSection(pmRoot,normalizedSchema.files.fields,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.fields),filePathForSchemaSection(pmRoot,normalizedSchema.files.workflows,DEFAULT_RUNTIME_SCHEMA_FILE_PATHS.workflows)]}async function cacheSettingsReadResult(pmRoot,trackedPaths,result){const signatures=await collectSettingsReadCacheSignatures(trackedPaths);setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures,value:cloneSettingsReadResult(result)})}async function cacheSettingsReadResultSafe(pmRoot,trackedPaths,result){try{await cacheSettingsReadResult(pmRoot,trackedPaths,result)}catch{clearSettingsReadCache(pmRoot)}}function findSettingsReadCacheSignature(signatures,targetPath){return signatures.find(signature=>signature.path===targetPath)}function selectedSettingsReadCacheSignaturesEqual(before,after,targetPaths){for(const targetPath of targetPaths){const beforeSignature=findSettingsReadCacheSignature(before,targetPath),afterSignature=findSettingsReadCacheSignature(after,targetPath);if(!beforeSignature||!afterSignature||!settingsReadCacheSignaturesEqual([beforeSignature],[afterSignature]))return!1}return!0}async function cacheSettingsReadResultIfStable(pmRoot,trackedPaths,result,stableSignatures,stablePaths){try{const currentSignatures=await collectSettingsReadCacheSignatures(trackedPaths);if(!selectedSettingsReadCacheSignaturesEqual(stableSignatures,currentSignatures,stablePaths)){clearSettingsReadCache(pmRoot);return}setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:currentSignatures,value:cloneSettingsReadResult(result)})}catch{clearSettingsReadCache(pmRoot)}}function resolvePersistedFileBackedSchemaSections(settings,source){const normalizedSchema=normalizeRuntimeSchemaSettings(settings.schema),currentItemTypeDefinitions=normalizeItemTypeDefinitions(settings.item_types?.definitions);if(!source)return{item_type_definitions:currentItemTypeDefinitions,schema_statuses:normalizedSchema.statuses,schema_fields:normalizedSchema.fields,schema_type_workflows:normalizedSchema.type_workflows};const currentTypeWorkflows=normalizedSchema.type_workflows??[],itemTypeDefinitionsUnchanged=stableValueEquals(currentItemTypeDefinitions,source.runtime_item_type_definitions),schemaStatusesUnchanged=stableValueEquals(normalizedSchema.statuses,source.runtime_schema_statuses),schemaFieldsUnchanged=stableValueEquals(normalizedSchema.fields,source.runtime_schema_fields),schemaTypeWorkflowsUnchanged=stableValueEquals(currentTypeWorkflows,source.runtime_schema_type_workflows);return{item_type_definitions:itemTypeDefinitionsUnchanged?source.has_source_item_type_definitions?normalizeItemTypeDefinitions(source.source_item_type_definitions):[]:currentItemTypeDefinitions,schema_statuses:schemaStatusesUnchanged?source.has_source_schema_statuses?structuredClone(source.source_schema_statuses):[]:normalizedSchema.statuses,schema_fields:schemaFieldsUnchanged?source.has_source_schema_fields?structuredClone(source.source_schema_fields):[]:normalizedSchema.fields,schema_type_workflows:schemaTypeWorkflowsUnchanged?source.has_source_schema_type_workflows?structuredClone(source.source_schema_type_workflows):void 0:normalizedSchema.type_workflows}}function buildFallbackSettingsReadResult(warning){return{settings:cloneDefaults(),metadata:{has_explicit_item_format:!1},warnings:warning?[warning]:[]}}function hasExplicitItemFormat(raw){if(typeof raw!="object"||raw===null||Array.isArray(raw))return!1;const itemFormat=raw.item_format;return itemFormat==="toon"||itemFormat==="json_markdown"}function normalizeStringList(values){return[...new Set((values??[]).map(value=>value.trim()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeAgentGuidanceSettings(value){const defaults=SETTINGS_DEFAULTS.agent_guidance,templateVersion=value?.template_version;return{prompt_completed:value?.prompt_completed===!0,declined:value?.declined===!0,declined_at:typeof value?.declined_at=="string"?value.declined_at:defaults.declined_at,template_version:typeof templateVersion=="number"&&Number.isInteger(templateVersion)&&templateVersion>0?templateVersion:defaults.template_version,last_checked_files:normalizeStringList(value?.last_checked_files??defaults.last_checked_files)}}function normalizeLowerStringList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function normalizeExtensionPolicyMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.mode}function normalizeExtensionTrustMode(value){return value==="off"||value==="warn"||value==="enforce"?value:SETTINGS_DEFAULTS.extensions.policy.trust_mode}function normalizeExtensionSandboxProfile(value){return value==="none"||value==="restricted"||value==="strict"?value:SETTINGS_DEFAULTS.extensions.policy.default_sandbox_profile}function normalizeExtensionPolicyOverride(override){const name=override.name.trim().toLowerCase();if(name.length===0)return null;const normalized={name};override.disabled===!0&&(normalized.disabled=!0),override.require_trusted===!0&&(normalized.require_trusted=!0),override.require_provenance===!0&&(normalized.require_provenance=!0),override.sandbox_profile!==void 0&&(normalized.sandbox_profile=normalizeExtensionSandboxProfile(override.sandbox_profile));const allowedCapabilities=normalizeLowerStringList(override.allowed_capabilities),blockedCapabilities=normalizeLowerStringList(override.blocked_capabilities),allowedSurfaces=normalizeLowerStringList(override.allowed_surfaces),blockedSurfaces=normalizeLowerStringList(override.blocked_surfaces),allowedCommands=normalizeLowerStringList(override.allowed_commands),blockedCommands=normalizeLowerStringList(override.blocked_commands),allowedActions=normalizeLowerStringList(override.allowed_actions),blockedActions=normalizeLowerStringList(override.blocked_actions),allowedServices=normalizeLowerStringList(override.allowed_services),blockedServices=normalizeLowerStringList(override.blocked_services);return allowedCapabilities.length>0&&(normalized.allowed_capabilities=allowedCapabilities),blockedCapabilities.length>0&&(normalized.blocked_capabilities=blockedCapabilities),allowedSurfaces.length>0&&(normalized.allowed_surfaces=allowedSurfaces),blockedSurfaces.length>0&&(normalized.blocked_surfaces=blockedSurfaces),allowedCommands.length>0&&(normalized.allowed_commands=allowedCommands),blockedCommands.length>0&&(normalized.blocked_commands=blockedCommands),allowedActions.length>0&&(normalized.allowed_actions=allowedActions),blockedActions.length>0&&(normalized.blocked_actions=blockedActions),allowedServices.length>0&&(normalized.allowed_services=allowedServices),blockedServices.length>0&&(normalized.blocked_services=blockedServices),normalized}function normalizeExtensionPolicyOverrides(overrides){const dedupedByName=new Map;for(const override of overrides??[]){const normalized=normalizeExtensionPolicyOverride(override);normalized&&dedupedByName.set(normalized.name,normalized)}return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function normalizePmMaxVersionExceededModeValue(value){return value==="block"||value==="warn"?value:void 0}function normalizePmMaxVersionExceededModeSetting(value){if(typeof value=="string")return normalizePmMaxVersionExceededModeValue(value);if(typeof value=="object"&&value!==null&&!Array.isArray(value)){const global2=normalizePmMaxVersionExceededModeValue(value.global),project=normalizePmMaxVersionExceededModeValue(value.project);return global2===void 0&&project===void 0?void 0:{...global2!==void 0?{global:global2}:{},...project!==void 0?{project}:{}}}}function normalizeExtensionPolicyList(policy,key){return normalizeLowerStringList(policy?.[key]??SETTINGS_DEFAULTS.extensions.policy[key])}function normalizeExtensionPolicySettings(policy){const pmMaxVersionExceededMode=normalizePmMaxVersionExceededModeSetting(policy?.pm_max_version_exceeded_mode);return{mode:normalizeExtensionPolicyMode(policy?.mode),trust_mode:normalizeExtensionTrustMode(policy?.trust_mode),...pmMaxVersionExceededMode!==void 0?{pm_max_version_exceeded_mode:pmMaxVersionExceededMode}:{},require_provenance:policy?.require_provenance===!0,trusted_extensions:normalizeExtensionPolicyList(policy,"trusted_extensions"),default_sandbox_profile:normalizeExtensionSandboxProfile(policy?.default_sandbox_profile),allowed_extensions:normalizeExtensionPolicyList(policy,"allowed_extensions"),blocked_extensions:normalizeExtensionPolicyList(policy,"blocked_extensions"),allowed_capabilities:normalizeExtensionPolicyList(policy,"allowed_capabilities"),blocked_capabilities:normalizeExtensionPolicyList(policy,"blocked_capabilities"),allowed_surfaces:normalizeExtensionPolicyList(policy,"allowed_surfaces"),blocked_surfaces:normalizeExtensionPolicyList(policy,"blocked_surfaces"),allowed_commands:normalizeExtensionPolicyList(policy,"allowed_commands"),blocked_commands:normalizeExtensionPolicyList(policy,"blocked_commands"),allowed_actions:normalizeExtensionPolicyList(policy,"allowed_actions"),blocked_actions:normalizeExtensionPolicyList(policy,"blocked_actions"),allowed_services:normalizeExtensionPolicyList(policy,"allowed_services"),blocked_services:normalizeExtensionPolicyList(policy,"blocked_services"),extension_overrides:normalizeExtensionPolicyOverrides(policy?.extension_overrides??SETTINGS_DEFAULTS.extensions.policy.extension_overrides)}}function normalizeValidationMetadataRequiredFields(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase().replaceAll("-","_")))].filter(value=>value.length>0).sort((left,right)=>left.localeCompare(right)).filter(value=>["author","acceptance_criteria","estimated_minutes","close_reason","reviewer","risk","confidence","sprint","release"].includes(value))}function normalizeValidationPatternList(values){return[...new Set((values??[]).map(value=>value.trim().toLowerCase()).filter(value=>value.length>0))].sort((left,right)=>left.localeCompare(right))}function valueOrDefault(value,fallback){return value===void 0?fallback:value}function recordOrEmpty(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)?value:{}}function arrayOrEmpty(value){return Array.isArray(value)?value:[]}function buildValidationSettings(settings,defaults,governance){return{...defaults.validation,...settings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(settings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_stale_blocker_reason_patterns??defaults.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_blocked_reason_patterns??defaults.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_resolution_patterns??defaults.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(settings.validation?.lifecycle_closure_like_actual_result_patterns??defaults.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(settings.validation?.estimate_defaults_by_type)}}function buildTelemetrySettings(settings,defaults){return{enabled:settings.telemetry?.enabled??defaults.telemetry.enabled,first_run_prompt_completed:settings.telemetry?.first_run_prompt_completed??defaults.telemetry.first_run_prompt_completed,capture_level:settings.telemetry?.capture_level??defaults.telemetry.capture_level,endpoint:settings.telemetry?.endpoint??defaults.telemetry.endpoint,installation_id:settings.telemetry?.installation_id??defaults.telemetry.installation_id,retention_days:settings.telemetry?.retention_days??defaults.telemetry.retention_days}}function buildSearchSettings(settings,defaults){return{...defaults.search,...settings.search,default_mode:normalizeSearchDefaultMode(settings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(settings.search?.mutation_refresh_policy),query_expansion:{...defaults.search.query_expansion,...settings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(settings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(settings.search?.query_expansion?.provider)},rerank:{...defaults.search.rerank,...settings.search?.rerank,enabled:normalizeSearchRerankEnabled(settings.search?.rerank?.enabled),model:normalizeSearchRerankModel(settings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(settings.search?.rerank?.top_k)}}}function buildVectorStoreSettings(settings,defaults){return{adapter:settings.vector_store.adapter??defaults.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(settings.vector_store.collection_name),qdrant:{...defaults.vector_store.qdrant,...settings.vector_store.qdrant},lancedb:{...defaults.vector_store.lancedb,...settings.vector_store.lancedb}}}function normalizeSettingsItemFormat(settings,defaults){return settings.item_format==="json_markdown"?"toon":settings.item_format??defaults.item_format}function buildContextSettings(settings,defaults){return{default_depth:settings.context?.default_depth??defaults.context.default_depth,activity_limit:settings.context?.activity_limit??defaults.context.activity_limit,stale_threshold_days:settings.context?.stale_threshold_days??defaults.context.stale_threshold_days,next_ranking_policy:settings.context?.next_ranking_policy??defaults.context.next_ranking_policy,sections:{...defaults.context.sections,...settings.context?.sections}}}function buildProviderSettings(settings,defaults){return{openai:{...defaults.providers.openai,...settings.providers.openai},ollama:{...defaults.providers.ollama,...settings.providers.ollama}}}function normalizeItemTypeDefinitions(definitions){const normalized=(definitions??[]).map(definition=>normalizeItemTypeDefinition(definition)).filter(definition=>definition!==null),dedupedByName=new Map;for(const definition of normalized)dedupedByName.set(definition.name.toLowerCase(),definition);return[...dedupedByName.values()].sort((left,right)=>left.name.localeCompare(right.name))}function mergeSettings(settings){const defaults=cloneDefaults(),governance=resolveGovernanceKnobs({governance:settings.governance??{preset:"default"}});return{...defaults,...settings,item_format:normalizeSettingsItemFormat(settings,defaults),locks:{...defaults.locks,...settings.locks},ids:{...defaults.ids,...settings.ids},agent_identity:structuredClone(settings.agent_identity??defaults.agent_identity),mutation_guard:{...defaults.mutation_guard,...settings.mutation_guard},checkpoints:{...defaults.checkpoints,...settings.checkpoints},output:{...defaults.output,...settings.output},ux:{...defaults.ux,...settings.ux},history:{...defaults.history,...settings.history,compact_policy:{...defaults.history.compact_policy,...settings.history?.compact_policy}},validation:buildValidationSettings(settings,defaults,governance),governance,workflow:{definition_of_done:[...settings.workflow?.definition_of_done??defaults.workflow.definition_of_done]},testing:{record_results_to_items:settings.testing?.record_results_to_items??defaults.testing.record_results_to_items,allow_untrusted_linked_tests:settings.testing?.allow_untrusted_linked_tests??defaults.testing.allow_untrusted_linked_tests},telemetry:buildTelemetrySettings(settings,defaults),agent_guidance:normalizeAgentGuidanceSettings(settings.agent_guidance??defaults.agent_guidance),item_types:{definitions:normalizeItemTypeDefinitions(settings.item_types?.definitions)},schema:normalizeRuntimeSchemaSettings(settings.schema??defaults.schema),context:buildContextSettings(settings,defaults),extensions:{enabled:[...settings.extensions.enabled],disabled:[...settings.extensions.disabled],policy:normalizeExtensionPolicySettings(settings.extensions.policy??defaults.extensions.policy)},search:buildSearchSettings(settings,defaults),providers:buildProviderSettings(settings,defaults),vector_store:buildVectorStoreSettings(settings,defaults)}}function orderSerializedSettingsSections(ordered){ordered.agent_identity=orderObject(ordered.agent_identity,["probes_enabled","identity_vocabulary","harness_signals"]);const orderedAgentIdentity=ordered.agent_identity;Object.hasOwn(orderedAgentIdentity,"identity_vocabulary")&&(orderedAgentIdentity.identity_vocabulary=orderObject(recordOrEmpty(orderedAgentIdentity.identity_vocabulary),["version","aliases"])),ordered.agent_identity.harness_signals=arrayOrEmpty(ordered.agent_identity.harness_signals).map(entry=>orderObject(recordOrEmpty(entry),["harness","environment_keys","model_environment_keys","session_environment_keys","provenance_environment_keys","provenance_resolvers","provenance_unavailable_dimensions","argv_markers","client_names"])),ordered.locks=orderObject(ordered.locks,["ttl_seconds","wait_ms"]),ordered.ids=orderObject(ordered.ids,["token_length"]),ordered.mutation_guard=orderObject(ordered.mutation_guard,["require_attributed_author","secret_guard","stale_in_progress_hours"]),ordered.checkpoints=orderObject(ordered.checkpoints,["retention_days"]),ordered.output=orderObject(ordered.output,["default_format"]),ordered.ux=orderObject(ordered.ux,["deprecation_hints"]),ordered.history=orderObject(ordered.history,["missing_stream","compact_policy"]),ordered.validation=orderObject(ordered.validation,["sprint_release_format","parent_reference","metadata_profile","metadata_required_fields","lifecycle_stale_blocker_reason_patterns","lifecycle_closure_like_blocked_reason_patterns","lifecycle_closure_like_resolution_patterns","lifecycle_closure_like_actual_result_patterns","estimate_defaults_by_type"]),ordered.governance=orderObject(ordered.governance,["preset","ownership_enforcement","create_mode_default","close_validation_default","require_close_reason","parent_reference","metadata_profile","force_required_for_stale_lock","create_default_type","workflow_enforcement","duplicate_detection_mode","duplicate_detection_threshold","duplicate_detection_limit"]),ordered.workflow=orderObject(ordered.workflow,["definition_of_done"]),ordered.testing=orderObject(ordered.testing,["record_results_to_items","allow_untrusted_linked_tests"]),ordered.telemetry=orderObject(ordered.telemetry,["enabled","first_run_prompt_completed","capture_level","endpoint","installation_id","retention_days"]),ordered.agent_guidance=orderObject(ordered.agent_guidance,["prompt_completed","declined","declined_at","template_version","last_checked_files"]),ordered.item_types=orderObject(ordered.item_types,["definitions"]),ordered.schema=orderObject(ordered.schema,["version","files","statuses","fields","workflow","type_workflows","unknown_field_policy"]),ordered.schema.files=orderObject(recordOrEmpty(ordered.schema.files),["types","statuses","fields","workflows"]),ordered.schema.workflow=orderObject(recordOrEmpty(ordered.schema.workflow),["draft_status","open_status","in_progress_status","blocked_status","close_status","canceled_status"]),ordered.context=orderObject(ordered.context,["default_depth","activity_limit","stale_threshold_days","next_ranking_policy","sections"]),ordered.context.sections=orderObject(recordOrEmpty(ordered.context.sections),["hierarchy","activity","progress","blockers","files","workload","staleness","tests"]),ordered.extensions=orderObject(ordered.extensions,["enabled","disabled","policy"]),ordered.extensions.policy=orderObject(recordOrEmpty(ordered.extensions.policy),["mode","trust_mode","pm_max_version_exceeded_mode","require_provenance","trusted_extensions","default_sandbox_profile","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"]),ordered.extensions.policy.extension_overrides=arrayOrEmpty(ordered.extensions.policy.extension_overrides).map(entry=>orderObject(recordOrEmpty(entry),["name","disabled","require_trusted","require_provenance","sandbox_profile","allowed_capabilities","blocked_capabilities","allowed_surfaces","blocked_surfaces","allowed_commands","blocked_commands","allowed_actions","blocked_actions","allowed_services","blocked_services"])),ordered.search=orderObject(ordered.search,["score_threshold","hybrid_semantic_weight","max_results","embedding_model","embedding_corpus_max_characters","embedding_batch_size","embedding_timeout_ms","scanner_max_batch_retries","provider","default_mode","mutation_refresh_policy","query_expansion","rerank"]),ordered.search.query_expansion=orderObject(recordOrEmpty(ordered.search.query_expansion),["enabled","provider"]),ordered.search.rerank=orderObject(recordOrEmpty(ordered.search.rerank),["enabled","model","top_k"]),ordered.providers=orderObject(ordered.providers,["openai","ollama"]),ordered.providers.openai=orderObject(recordOrEmpty(ordered.providers.openai),["base_url","api_key","model"]),ordered.providers.ollama=orderObject(recordOrEmpty(ordered.providers.ollama),["base_url","model"]),ordered.vector_store=orderObject(ordered.vector_store,["adapter","collection_name","qdrant","lancedb"]),ordered.vector_store.qdrant=orderObject(recordOrEmpty(ordered.vector_store.qdrant),["url","api_key"]),ordered.vector_store.lancedb=orderObject(recordOrEmpty(ordered.vector_store.lancedb),["path"])}function buildSerializeBaseSettings(settings){return{...settings,locks:valueOrDefault(settings.locks,SETTINGS_DEFAULTS.locks),ids:valueOrDefault(settings.ids,SETTINGS_DEFAULTS.ids),agent_identity:valueOrDefault(settings.agent_identity,SETTINGS_DEFAULTS.agent_identity),mutation_guard:valueOrDefault(settings.mutation_guard,SETTINGS_DEFAULTS.mutation_guard),checkpoints:valueOrDefault(settings.checkpoints,SETTINGS_DEFAULTS.checkpoints),output:valueOrDefault(settings.output,SETTINGS_DEFAULTS.output),ux:valueOrDefault(settings.ux,SETTINGS_DEFAULTS.ux),history:valueOrDefault(settings.history,SETTINGS_DEFAULTS.history),validation:valueOrDefault(settings.validation,SETTINGS_DEFAULTS.validation),workflow:valueOrDefault(settings.workflow,SETTINGS_DEFAULTS.workflow),testing:valueOrDefault(settings.testing,SETTINGS_DEFAULTS.testing),telemetry:valueOrDefault(settings.telemetry,SETTINGS_DEFAULTS.telemetry),agent_guidance:valueOrDefault(settings.agent_guidance,SETTINGS_DEFAULTS.agent_guidance),item_types:valueOrDefault(settings.item_types,SETTINGS_DEFAULTS.item_types),schema:valueOrDefault(settings.schema,SETTINGS_DEFAULTS.schema),context:valueOrDefault(settings.context,SETTINGS_DEFAULTS.context),extensions:valueOrDefault(settings.extensions,SETTINGS_DEFAULTS.extensions),search:valueOrDefault(settings.search,SETTINGS_DEFAULTS.search),providers:valueOrDefault(settings.providers,SETTINGS_DEFAULTS.providers),vector_store:valueOrDefault(settings.vector_store,SETTINGS_DEFAULTS.vector_store)}}function buildSerializedValidationSettings(baseSettings,governance){return{...baseSettings.validation,parent_reference:governance.parent_reference,metadata_profile:governance.metadata_profile,metadata_required_fields:normalizeValidationMetadataRequiredFields(baseSettings.validation?.metadata_required_fields),lifecycle_stale_blocker_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_stale_blocker_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_stale_blocker_reason_patterns),lifecycle_closure_like_blocked_reason_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_blocked_reason_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_blocked_reason_patterns),lifecycle_closure_like_resolution_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_resolution_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_resolution_patterns),lifecycle_closure_like_actual_result_patterns:normalizeValidationPatternList(baseSettings.validation?.lifecycle_closure_like_actual_result_patterns??SETTINGS_DEFAULTS.validation.lifecycle_closure_like_actual_result_patterns),estimate_defaults_by_type:normalizeEstimateDefaultOverrides(baseSettings.validation?.estimate_defaults_by_type)}}function buildSerializedSearchSettings(baseSettings){return{...SETTINGS_DEFAULTS.search,...baseSettings.search,default_mode:normalizeSearchDefaultMode(baseSettings.search?.default_mode),mutation_refresh_policy:normalizeSearchMutationRefreshPolicy(baseSettings.search?.mutation_refresh_policy),query_expansion:{...SETTINGS_DEFAULTS.search.query_expansion,...baseSettings.search?.query_expansion,enabled:normalizeSearchQueryExpansionEnabled(baseSettings.search?.query_expansion?.enabled),provider:normalizeSearchQueryExpansionProvider(baseSettings.search?.query_expansion?.provider)},rerank:{...SETTINGS_DEFAULTS.search.rerank,...baseSettings.search?.rerank,enabled:normalizeSearchRerankEnabled(baseSettings.search?.rerank?.enabled),model:normalizeSearchRerankModel(baseSettings.search?.rerank?.model),top_k:normalizeSearchRerankTopK(baseSettings.search?.rerank?.top_k)}}}function buildSerializedContextSettings(baseSettings){return{default_depth:baseSettings.context?.default_depth??SETTINGS_DEFAULTS.context.default_depth,activity_limit:baseSettings.context?.activity_limit??SETTINGS_DEFAULTS.context.activity_limit,stale_threshold_days:baseSettings.context?.stale_threshold_days??SETTINGS_DEFAULTS.context.stale_threshold_days,next_ranking_policy:baseSettings.context?.next_ranking_policy??SETTINGS_DEFAULTS.context.next_ranking_policy,sections:{...SETTINGS_DEFAULTS.context.sections,...baseSettings.context?.sections}}}function buildSerializedVectorStoreSettings(baseSettings){return{...baseSettings.vector_store,adapter:baseSettings.vector_store?.adapter??SETTINGS_DEFAULTS.vector_store.adapter,collection_name:normalizeVectorStoreCollectionName(baseSettings.vector_store?.collection_name),qdrant:{...baseSettings.vector_store?.qdrant},lancedb:{...baseSettings.vector_store?.lancedb}}}function buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections){return{...baseSettings,item_format:"toon",validation:buildSerializedValidationSettings(baseSettings,governance),governance,agent_guidance:normalizeAgentGuidanceSettings(baseSettings.agent_guidance),item_types:{definitions:persistedFileBackedSections.item_type_definitions},schema:{...normalizedSchema,statuses:persistedFileBackedSections.schema_statuses,fields:persistedFileBackedSections.schema_fields,type_workflows:persistedFileBackedSections.schema_type_workflows},search:buildSerializedSearchSettings(baseSettings),context:buildSerializedContextSettings(baseSettings),extensions:{enabled:normalizeStringList(baseSettings.extensions?.enabled),disabled:normalizeStringList(baseSettings.extensions?.disabled),policy:normalizeExtensionPolicySettings(baseSettings.extensions?.policy)},vector_store:buildSerializedVectorStoreSettings(baseSettings)}}function overlayPresentSettingsSource(target,source){for(const key of Object.keys(source)){const value=Reflect.get(source,key),existing=target[key];typeof value=="object"&&value!==null&&!Array.isArray(value)&&typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?overlayPresentSettingsSource(existing,value):target[key]=structuredClone(value)}}function applySettingsDelta(target,baseline,current){const keys=new Set([...Object.keys(baseline),...Object.keys(current)]);for(const key of keys){const before=baseline[key],after=current[key];if(!stableValueEquals(before,after)){if(after===void 0){delete target[key];continue}if(typeof before=="object"&&before!==null&&!Array.isArray(before)&&typeof after=="object"&&after!==null&&!Array.isArray(after)){const existing=target[key],nestedTarget=typeof existing=="object"&&existing!==null&&!Array.isArray(existing)?existing:{};applySettingsDelta(nestedTarget,before,after),Object.keys(nestedTarget).length>0?target[key]=nestedTarget:delete target[key];continue}target[key]=structuredClone(after)}}}const SETTINGS_TOP_LEVEL_KEY_ORDER=["version","id_prefix","ids","author_default","agent_identity","mutation_guard","item_format","locks","checkpoints","output","ux","history","validation","governance","workflow","testing","telemetry","agent_guidance","item_types","schema","context","extensions","search","providers","vector_store"];function buildOrderedSettingsForSerialization(settings,persistSource){const baseSettings=buildSerializeBaseSettings(settings),governance=resolveGovernanceKnobs(baseSettings),normalizedSchema=normalizeRuntimeSchemaSettings(baseSettings.schema),persistedFileBackedSections=resolvePersistedFileBackedSchemaSections(baseSettings,persistSource),normalizedSettings=buildNormalizedSettingsForSerialization(baseSettings,governance,normalizedSchema,persistedFileBackedSections),ordered=orderObject({...normalizedSettings,governance:normalizeGovernanceForPersist(governance)},SETTINGS_TOP_LEVEL_KEY_ORDER);return orderSerializedSettingsSections(ordered),ordered}function serializeSettings(settings,options={}){const persistSource=options.source===void 0?options.persist_source:buildSettingsPersistSourceSnapshot(options.source.validated,mergeSettings(options.source.validated)),ordered=buildOrderedSettingsForSerialization(settings,persistSource);if(persistSource){const baselineSettings=mergeSettings(persistSource.source_settings);baselineSettings.item_types={definitions:structuredClone(persistSource.runtime_item_type_definitions)},baselineSettings.schema={...baselineSettings.schema,statuses:structuredClone(persistSource.runtime_schema_statuses),fields:structuredClone(persistSource.runtime_schema_fields),type_workflows:structuredClone(persistSource.runtime_schema_type_workflows)};const baseline=buildOrderedSettingsForSerialization(baselineSettings,persistSource);options.source!==void 0&&overlayPresentSettingsSource(baseline,options.source.validated);const sparse=structuredClone(options.source===void 0?persistSource.source_settings:options.source.raw);return applySettingsDelta(sparse,baseline,ordered),`${JSON.stringify(orderObject(sparse,SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
|
|
2
2
|
`}return`${JSON.stringify(ordered,null,2)}
|
|
3
3
|
`}async function readConfigurationOnlySettings(pmRoot){let root;try{root=await realpath(pmRoot)}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}const file=getSettingsPath(root);let entry;try{entry=await lstat(file)}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}if(!entry.isFile())throw transactionPreviewNonRegularFileError("settings.json");let raw;try{raw=await readRegularFile(file,transactionPreviewNonRegularFileError("settings.json"))}catch(error){if(isFileAbsentError(error))return buildFallbackSettingsReadResult();throw error}let parsed;try{parsed=JSON.parse(raw)}catch{return buildFallbackSettingsReadResult("settings_read_invalid_json")}const validated=validateSettings(parsed);return validated.success?{settings:mergeSettings(validated.data),metadata:{has_explicit_item_format:hasExplicitItemFormat(parsed)},warnings:validated.data.item_format==="json_markdown"?["settings_item_format_legacy_json_markdown_coerced_to_toon"]:[]}:buildFallbackSettingsReadResult("settings_read_invalid_schema")}async function readSettingsWithMetadata(pmRoot){if(isConfigurationOnlySettingsRead(pmRoot))return readConfigurationOnlySettings(pmRoot);const settingsPath=getSettingsPath(pmRoot);let trackedPathsForFailure=[settingsPath];await runActiveOnReadHooks({path:settingsPath,scope:"project"});const cachedResult=getSettingsReadCacheEntry(pmRoot);if(cachedResult){const currentSignatures=await collectSettingsReadCacheSignatures(cachedResult.tracked_paths);if(settingsReadCacheSignaturesEqual(currentSignatures,cachedResult.signatures))return cloneSettingsReadResult(cachedResult.value)}const settingsOnlySignatures=await collectSettingsReadCacheSignatures([settingsPath]);let raw;try{raw=await readFileIfExists(settingsPath)}catch{return buildFallbackSettingsReadResult("settings_read_fs_error")}if(raw===null){const fallback=buildFallbackSettingsReadResult();return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsOnlySignatures,[settingsPath]),fallback}const settingsSignaturesAfterRead=await collectSettingsReadCacheSignatures([settingsPath]);if(!settingsReadCacheSignaturesEqual(settingsOnlySignatures,settingsSignaturesAfterRead))return clearSettingsReadCache(pmRoot),readSettingsWithMetadata(pmRoot);let parsed;try{parsed=JSON.parse(raw)}catch{const fallback=buildFallbackSettingsReadResult("settings_read_invalid_json");return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsSignaturesAfterRead,[settingsPath]),fallback}const validated=validateSettings(parsed);if(!validated.success){const fallback=buildFallbackSettingsReadResult("settings_read_invalid_schema");return await cacheSettingsReadResultIfStable(pmRoot,[settingsPath],fallback,settingsSignaturesAfterRead,[settingsPath]),fallback}try{const mergedSettings=mergeSettings(validated.data),trackedPaths=resolveSettingsReadTrackedPaths(pmRoot,mergedSettings.schema,settingsPath);trackedPathsForFailure=trackedPaths;const signaturesBeforeSchemaLoad=await collectSettingsReadCacheSignatures(trackedPaths),loadedSchemaSections=await loadRuntimeSchemaFromOptionalFiles(pmRoot,mergedSettings.schema),signaturesAfterSchemaLoad=await collectSettingsReadCacheSignatures(trackedPaths),settings={...mergedSettings,item_types:{definitions:normalizeItemTypeDefinitions([...mergedSettings.item_types.definitions,...arrayOrEmpty(loadedSchemaSections.type_definitions_from_file)])},schema:loadedSchemaSections.schema};attachSettingsPersistSourceSnapshot(settings,buildSettingsPersistSourceSnapshot(validated.data,settings));const result={settings,metadata:{has_explicit_item_format:hasExplicitItemFormat(parsed)},warnings:[...validated.data.item_format==="json_markdown"?["settings_item_format_legacy_json_markdown_coerced_to_toon"]:[],...loadedSchemaSections.warnings]};return settingsReadCacheSignaturesEqual(signaturesBeforeSchemaLoad,signaturesAfterSchemaLoad)?setSettingsReadCacheEntry(pmRoot,{tracked_paths:trackedPaths,signatures:signaturesAfterSchemaLoad,value:cloneSettingsReadResult(result)}):clearSettingsReadCache(pmRoot),result}catch{const fallback=buildFallbackSettingsReadResult("settings_read_merge_failed");return await cacheSettingsReadResultSafe(pmRoot,trackedPathsForFailure,fallback),fallback}}async function readSettings(pmRoot){return(await readSettingsWithMetadata(pmRoot)).settings}async function writeSettings(pmRoot,settings,op=SETTINGS_WRITE_OP){const settingsPath=getSettingsPath(pmRoot),source=getSettingsPersistSourceSnapshot(settings),afterRaw=serializeSettings(settings,{persist_source:source}),proposed=JSON.parse(afterRaw);try{await mutateWorkspaceJsonWithHistory({pmRoot,filePath:settingsPath,mutate:beforeRaw=>{let current=null;if(beforeRaw!==null)try{current=JSON.parse(beforeRaw)}catch{throw new PmCliError("Existing settings.json is malformed; the settings write was refused.",EXIT_CODE.USAGE,{code:"settings_write_invalid_existing_json",reason:"existing_settings_json_malformed",why:"Writing defaults over malformed settings could destroy intended project configuration.",nextSteps:["Repair the syntax in .agents/pm/settings.json, then retry the original command.","Run pm health to confirm the settings warning has cleared."]})}return{raw:source?`${JSON.stringify(orderObject(reconcileSettingsSnapshot(source.persisted_settings,proposed,current),SETTINGS_TOP_LEVEL_KEY_ORDER),null,2)}
|
|
4
4
|
`:afterRaw,result:void 0}},op,author:resolveAuthor(void 0,settings.author_default),lockTtlSeconds:settings.locks.ttl_seconds,lockWaitMs:settings.locks.wait_ms,recordCreation:!1}),source&&attachSettingsPersistSourceSnapshot(settings,{...source,persisted_settings:structuredClone(proposed)}),await runActiveOnWriteHooks({path:settingsPath,scope:"project",op})}finally{clearSettingsReadCache(pmRoot)}}const settingsStoreTestOnly={applySettingsDelta,hasExplicitItemFormat,buildSettingsPersistSourceSnapshot,cacheSettingsReadResultIfStable,cacheSettingsReadResultSafe,mergeSettings,normalizeExtensionPolicySettings,normalizeExtensionPolicyOverride,normalizeExtensionPolicyOverrides,normalizeExtensionPolicyMode,normalizePmMaxVersionExceededModeSetting,normalizeExtensionSandboxProfile,normalizeExtensionTrustMode,normalizeLowerStringList,normalizeStringList,valueOrDefault,arrayOrEmpty,normalizeValidationPatternList,normalizeValidationMetadataRequiredFields,resolveSettingsReadTrackedPaths,resolvePersistedFileBackedSchemaSections,selectedSettingsReadCacheSignaturesEqual};export{isConfigurationOnlySettingsRead,mergeSettings,normalizeItemTypeDefinitions,persistSelectedItemFormat,readSettings,readSettingsWithMetadata,resolveGovernanceKnobs,runWithConfigurationOnlySettings,serializeSettings,settingsStoreTestOnly,writeSettings};
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/** Supported explicit classifications for intentional telemetry delivery. */
|
|
2
2
|
export declare const PM_TELEMETRY_SOURCE_CONTEXT_VALUES:readonly ["user","automation","test","dogfood"];
|
|
3
|
+
/** Resolve privacy-bounded execution attribution without consent, identity or network work. */
|
|
4
|
+
export declare function resolveTelemetrySourceAttribution(options?:{
|
|
5
|
+
json?:boolean;
|
|
6
|
+
quiet?:boolean;
|
|
7
|
+
},env?:Readonly<Record<string,string | undefined>>,interactive?:boolean):{
|
|
8
|
+
source_context:typeof PM_TELEMETRY_SOURCE_CONTEXT_VALUES[number];
|
|
9
|
+
source_context_source:"env_override" | "inferred" | "env_override_rejected";
|
|
10
|
+
};
|
|
3
11
|
/** Share native and package test signals across consent, attribution and flush lifetime. */
|
|
4
12
|
export declare function isTelemetryTestEnvironment(env?:Readonly<Record<string,string | undefined>>):boolean;
|
|
5
13
|
/** Fixed core reads eligible only after runtime ownership has been established. */
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ac3b0f55-7faf-5fa6-b01d-304e87acb9a2")}catch{}})();const TRUE_VALUES=new Set(["1","true","yes","on"]),PM_TELEMETRY_SOURCE_CONTEXT_VALUES=["user","automation","test","dogfood"],SOURCE_CONTEXTS=new Set(PM_TELEMETRY_SOURCE_CONTEXT_VALUES);function resolveTelemetrySourceAttribution(options={},env=process.env,interactive=process.stdin.isTTY===!0&&process.stdout.isTTY===!0){const override=(env.PM_TELEMETRY_SOURCE_CONTEXT??"").trim().toLowerCase();if(SOURCE_CONTEXTS.has(override))return{source_context:override,source_context_source:"env_override"};const source=override?"env_override_rejected":"inferred";return isTelemetryTestEnvironment(env)?{source_context:"test",source_context_source:source}:{source_context:!interactive||telemetryEnvironmentFlag("CI",env)||options.json===!0||options.quiet===!0?"automation":"user",source_context_source:source}}function isTelemetryTestEnvironment(env=process.env){return typeof env.VITEST=="string"||typeof env.VITEST_WORKER_ID=="string"||typeof env.NODE_TEST_CONTEXT=="string"||(env.NODE_ENV??"").trim().toLowerCase()==="test"}const TELEMETRY_SAMPLEABLE_READS=new Set(["stats","ops stats","list","get","next","context","activity","aggregate"]);function resolveTelemetryReadSampleRate(command,noExtensions,env=process.env){const raw=env.PM_TELEMETRY_READ_SAMPLE_RATE?.trim();if(!raw||!noExtensions||!TELEMETRY_SAMPLEABLE_READS.has(command))return 1;const rate=Number(raw);return Number.isFinite(rate)&&rate>0&&rate<=1?rate:1}function telemetryEnvironmentFlag(key,env){return TRUE_VALUES.has((env[key]??"").trim().toLowerCase())}function resolveTelemetryEnvironmentPolicy(env=process.env){const doNotTrack=telemetryEnvironmentFlag("DO_NOT_TRACK",env),override=(env.PM_TELEMETRY_SOURCE_CONTEXT??"").trim().toLowerCase(),testSuppressed=isTelemetryTestEnvironment(env)&&!SOURCE_CONTEXTS.has(override)&&!telemetryEnvironmentFlag("PM_TELEMETRY_SEND_TEST_EVENTS",env);return{telemetry_disabled:doNotTrack||testSuppressed||telemetryEnvironmentFlag("PM_TELEMETRY_DISABLED",env)||telemetryEnvironmentFlag("PM_NO_TELEMETRY",env),do_not_track:doNotTrack,test_suppressed:testSuppressed}}export{PM_TELEMETRY_SOURCE_CONTEXT_VALUES,TELEMETRY_SAMPLEABLE_READS,isTelemetryTestEnvironment,resolveTelemetryEnvironmentPolicy,resolveTelemetryReadSampleRate,resolveTelemetrySourceAttribution};
|
|
2
2
|
//# sourceMappingURL=policy.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
-
`,{createParentDirectories:!parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV])})},globalPmRoot)}catch{}}function isSensitiveKey(key){const normalized=key.trim().toLowerCase().replaceAll("-","_").replaceAll(/[^a-z0-9_]+/g,"_"),tokens=normalized.split("_").filter(token=>token.length>0);return REDACTION_INPUT_KEYS.has(normalized)||SENSITIVE_KEYWORDS.some(keyword=>normalized===keyword||normalized.endsWith(`_${keyword}`)||tokens.includes(keyword))}function redactInlineSensitiveAssignments(input){return input.replaceAll(INLINE_SENSITIVE_ASSIGNMENT_PATTERN,(_match,key,delimiter)=>`${key}${delimiter}[redacted]`).replaceAll(INLINE_SENSITIVE_FLAG_PATTERN,(_match,flag,delimiter)=>`${flag}${delimiter}[redacted]`)}function redactAbsolutePathTokens(input){return input.replaceAll(ABSOLUTE_PATH_TOKEN_PATTERN,(_match,prefix)=>`${prefix}[redacted_path]`)}function isAsciiLetterOrDigitCode(code){const isUpper=code>=65&&code<=90,isLower=code>=97&&code<=122,isDigit=code>=48&&code<=57;return isUpper||isLower||isDigit}function isEmailLocalCharacter(character){if(!character)return!1;const code=character.charCodeAt(0);return isAsciiLetterOrDigitCode(code)?!0:character==="."||character==="_"||character==="%"||character==="+"||character==="-"}function isEmailDomainCharacter(character){if(!character)return!1;const code=character.charCodeAt(0);return isAsciiLetterOrDigitCode(code)?!0:character==="."||character==="-"}function looksLikeEmailToken(token){const atIndex=token.indexOf("@");if(atIndex<=0||atIndex!==token.lastIndexOf("@")||atIndex===token.length-1)return!1;const localPart=token.slice(0,atIndex),domainPart=token.slice(atIndex+1),lastDot=domainPart.lastIndexOf(".");if(lastDot<=0||lastDot===domainPart.length-1||domainPart.length-(lastDot+1)<2)return!1;for(const character of localPart)if(!isEmailLocalCharacter(character))return!1;for(const character of domainPart)if(!isEmailDomainCharacter(character))return!1;return!0}function redactEmailTokens(input){let redacted="",cursor=0;for(;cursor<input.length;){const atIndex=input.indexOf("@",cursor);if(atIndex<0){redacted+=input.slice(cursor);break}let start=atIndex-1;for(;start>=cursor&&isEmailLocalCharacter(input[start]);)start-=1;start+=1;let end=atIndex+1;for(;end<input.length&&isEmailDomainCharacter(input[end]);)end+=1;const candidate=input.slice(start,end);if(looksLikeEmailToken(candidate)){redacted+=input.slice(cursor,start),redacted+="[redacted_email]",cursor=end;continue}redacted+=input.slice(cursor,atIndex+1),cursor=atIndex+1}return redacted}function sanitizeCommonSensitiveTokens(input){return redactEmailTokens(input).replaceAll(BEARER_TOKEN_PATTERN,"bearer [redacted_token]").replaceAll(PRIVATE_IP_PATTERN,"[redacted_ip]")}function sanitizeStringRedacted(input){const withoutCommonSensitiveTokens=sanitizeCommonSensitiveTokens(input),withoutInlineSecrets=redactInlineSensitiveAssignments(withoutCommonSensitiveTokens),withoutAbsolutePaths=redactAbsolutePathTokens(withoutInlineSecrets),trimmed=withoutAbsolutePaths.trim();return trimmed.startsWith("/")&&trimmed.length>1?"[redacted_path]":withoutAbsolutePaths.length>512?`${withoutAbsolutePaths.slice(0,509)}...`:withoutAbsolutePaths}function sanitizeStringMax(input){const withoutCommonSensitiveTokens=sanitizeCommonSensitiveTokens(input),withoutInlineSecrets=redactInlineSensitiveAssignments(withoutCommonSensitiveTokens),withoutAbsolutePaths=redactAbsolutePathTokens(withoutInlineSecrets),trimmed=withoutAbsolutePaths.trim();return trimmed.startsWith("/")&&trimmed.length>1?"[redacted_path]":withoutAbsolutePaths.length>2048?`${withoutAbsolutePaths.slice(0,2045)}...`:withoutAbsolutePaths}function sanitizeString(input,captureLevel="redacted"){return captureLevel==="max"?sanitizeStringMax(input):sanitizeStringRedacted(input)}function sanitizeValue(value,keyHint,captureLevel="redacted",depth=0){if(keyHint&&isSensitiveKey(keyHint))return"[redacted]";if(value==null)return value;if(typeof value=="string")return sanitizeString(value,captureLevel);if(typeof value=="number"||typeof value=="boolean")return value;if(depth>=TELEMETRY_SANITIZE_MAX_DEPTH)return"[depth_truncated]";if(Array.isArray(value))return value.slice(0,TELEMETRY_SANITIZE_MAX_ARRAY_ITEMS).map(entry=>sanitizeValue(entry,void 0,captureLevel,depth+1));if(typeof value=="object"){const record=value,sanitized={};for(const[key,nested]of Object.entries(record))sanitized[key]=sanitizeValue(nested,key,captureLevel,depth+1);return sanitized}return String(value)}function sanitizeCommandArgs(args,captureLevel="redacted"){const sanitized=[];let nextIsSensitiveValue=!1;for(const rawArg of args){const arg=sanitizeString(rawArg,captureLevel);if(nextIsSensitiveValue){sanitized.push("[redacted]"),nextIsSensitiveValue=!1;continue}if(arg.startsWith("--")){const withoutPrefix=arg.slice(2),delimiterIndex=withoutPrefix.indexOf("=");if(delimiterIndex>=0){const key=withoutPrefix.slice(0,delimiterIndex),value=withoutPrefix.slice(delimiterIndex+1);isSensitiveKey(key)?sanitized.push(`--${key}=[redacted]`):sanitized.push(`--${key}=${sanitizeString(value,captureLevel)}`);continue}if(isSensitiveKey(withoutPrefix)){sanitized.push(`--${withoutPrefix}`),nextIsSensitiveValue=!0;continue}}sanitized.push(arg)}return sanitized}function normalizeCaptureLevel(value){const normalized=value?.trim().toLowerCase();return normalized==="minimal"||normalized==="redacted"||normalized==="max"?normalized:"redacted"}function parseBooleanTrueLike(value){return BOOLEAN_TRUE_VALUES.has((value??"").trim().toLowerCase())}function resolveTelemetryHttpTimeoutMs(){const rawConfigured=process.env[PM_TELEMETRY_HTTP_TIMEOUT_MS_ENV]?.trim();if(!rawConfigured)return TELEMETRY_HTTP_TIMEOUT_DEFAULT_MS;const configured=Number(rawConfigured);return Number.isFinite(configured)?Math.min(TELEMETRY_HTTP_TIMEOUT_MAX_MS,Math.max(TELEMETRY_HTTP_TIMEOUT_MIN_MS,Math.trunc(configured))):TELEMETRY_HTTP_TIMEOUT_DEFAULT_MS}async function postTelemetryJson(endpoint,headers,body){const url=new URL(endpoint);if(globalThis.fetch!==NATIVE_FETCH){const controller=new AbortController;let timeout;const deadline=new Promise((_resolve,reject)=>{timeout=setTimeout(()=>{controller.abort(),reject(new Error("telemetry_http_timeout"))},resolveTelemetryHttpTimeoutMs())});try{return(await Promise.race([globalThis.fetch(endpoint,{method:"POST",headers,body,signal:controller.signal}),deadline])).status}finally{clearTimeout(timeout)}}const request=url.protocol==="https:"?httpsRequest:url.protocol==="http:"?httpRequest:void 0;if(!request)throw new Error(`telemetry_http_protocol_unsupported_${url.protocol}`);return new Promise((resolve,reject)=>{const timeoutMs=resolveTelemetryHttpTimeoutMs(),requestOptions={method:"POST",headers:{...headers,"content-length":Buffer.byteLength(body)},signal:AbortSignal.timeout(timeoutMs),autoSelectFamilyAttemptTimeout:Math.min(5e3,timeoutMs)},clientRequest=request(url,requestOptions,response=>{response.once("error",reject),response.once("end",()=>resolve(response.statusCode)),response.resume()});clientRequest.once("error",reject),clientRequest.end(body)})}function normalizePmVersion(value){const trimmed=typeof value=="string"?value.trim():"";return trimmed.length>0?trimmed:"0.0.0"}function normalizeTelemetryErrorCode(value){const normalized=value?.trim();return normalized&&normalized.length>0?normalized:void 0}function normalizeTelemetryExitCode(exitCode,ok){return Number.isFinite(exitCode)?Math.max(0,Math.trunc(exitCode)):ok?0:1}function normalizeTelemetryErrorCategory(params){if(!params.ok)return typeof params.errorCategory=="string"&¶ms.errorCategory.trim().length>0?params.errorCategory:typeof params.errorCode=="string"&¶ms.errorCode.trim().length>0?resolveTelemetryErrorCategory(params.errorCode):"unknown"}function resolveTelemetrySourceContext(globalOptions){const
|
|
3
|
-
`)),{source_context:inferTelemetrySourceContext(globalOptions),source_context_source:source}}function inferTelemetrySourceContext(globalOptions){if(isTelemetryTestEnvironment())return"test";const nonTty=process.stdin.isTTY!==!0||process.stdout.isTTY!==!0,ci=parseBooleanTrueLike(process.env.CI),scriptLikeMode=globalOptions.json===!0||globalOptions.quiet===!0;return nonTty||ci||scriptLikeMode?"automation":"user"}function hashWithInstallationId(installationId,value){return crypto.createHash("sha256").update(`${installationId}:${value}`).digest("hex")}function buildAuthorContextPayloadFields(captureLevel,installationId){const author=(readAuthorEnvironment()??"").trim(),agent=detectAgentIdentity({env:process.env,argv:process.argv}),hasAgentContext=agent.harness!==void 0||agent.model!==void 0;return captureLevel==="minimal"?{has_author_context:author.length>0,has_agent_context:hasAgentContext}:{agent_harness:agent.harness?TELEMETRY_HARNESSES.has(agent.harness)?agent.harness:"other":"none",ci:parseBooleanTrueLike(process.env.CI),...author.length>0?{author_context_hash:hashWithInstallationId(installationId,author)}:{},...agent.harness?{agent_harness_hash:hashWithInstallationId(installationId,agent.harness)}:{},...agent.model?{agent_model_hash:hashWithInstallationId(installationId,agent.model)}:{},...agent.model_source?{agent_model_source:agent.model_source}:{}}}function normalizeForHash(value,depth=0){if(value==null||typeof value=="string"||typeof value=="number"||typeof value=="boolean")return value;if(depth>=TELEMETRY_SANITIZE_MAX_DEPTH)return"[depth_truncated]";if(Array.isArray(value))return value.slice(0,TELEMETRY_SANITIZE_MAX_ARRAY_ITEMS).map(entry=>normalizeForHash(entry,depth+1));if(typeof value=="object"){const record=value,normalized={},sortedKeys=Object.keys(record).sort((left,right)=>left.localeCompare(right));for(const key of sortedKeys)normalized[key]=normalizeForHash(record[key],depth+1);return normalized}return String(value)}function hashTelemetryValue(installationId,value){return hashWithInstallationId(installationId,JSON.stringify(normalizeForHash(value)))}function hashCommandArgs(installationId,args){return{hashes:args.map(arg=>hashWithInstallationId(installationId,arg)),digest:hashWithInstallationId(installationId,args.join("\0"))}}function hashTelemetryErrorFingerprint(installationId,command,errorCode2,errorMessage){const normalizedMessage=sanitizeString(typeof errorMessage=="string"?errorMessage:"","redacted"),normalizedCode=typeof errorCode2=="string"&&errorCode2.length>0?errorCode2:"unknown_error",fingerprintSource=`${command}\0${normalizedCode}\0${normalizedMessage}`;return hashWithInstallationId(installationId,fingerprintSource)}function resolveOtelTracesEndpoint(){if(PM_TELEMETRY_OTEL_DISABLED_VALUES.has((process.env[PM_TELEMETRY_OTEL_DISABLED_ENV]??"").trim().toLowerCase()))return null;const directEndpoint=(process.env[OTEL_TRACES_ENDPOINT_ENV]??"").trim();if(directEndpoint.length>0)try{return new URL(directEndpoint).toString()}catch{return null}const baseEndpoint=(process.env[OTEL_BASE_ENDPOINT_ENV]??"").trim();if(baseEndpoint.length===0)return null;try{const url=new URL(baseEndpoint),normalizedPath=url.pathname.replace(/\/+$/,"");return normalizedPath.endsWith("/v1/traces")||(url.pathname=`${normalizedPath.length===0?"":normalizedPath}/v1/traces`),url.toString()}catch{return null}}function isoToUnixNano(iso){const parsedMs=Date.parse(iso),epochMs=Number.isNaN(parsedMs)?Date.now():parsedMs;return`${BigInt(epochMs)*1000000n}`}function otlpStringAttribute(key,value){return{key,value:{stringValue:value}}}function otlpBoolAttribute(key,value){return{key,value:{boolValue:value}}}function otlpIntAttribute(key,value){return{key,value:{intValue:String(Math.max(0,Math.trunc(value)))}}}function buildOtelSpanRequest(activeCommand,outcome,finishedAtIso,durationMs,sampleRate=1){const endpoint=activeCommand.otel_traces_endpoint;if(typeof endpoint!="string"||endpoint.trim().length===0||[activeCommand.otel_trace_id,activeCommand.otel_span_id].some(id=>typeof id!="string"||id.length===0))return null;const serviceNameCandidate=sanitizeString((process.env[OTEL_SERVICE_NAME_ENV]??"").trim()),serviceName=serviceNameCandidate.length>0?serviceNameCandidate:"pm-cli",normalizedExitCode=normalizeTelemetryExitCode(outcome.exit_code,outcome.ok),normalizedErrorCode=normalizeTelemetryErrorCode(outcome.error_code),normalizedErrorCategory=normalizeTelemetryErrorCategory({ok:outcome.ok,errorCode:normalizedErrorCode,errorCategory:outcome.error_category}),attributes=[otlpStringAttribute("pm.command",sanitizeString(activeCommand.command)),otlpStringAttribute("pm.version",activeCommand.pm_version),otlpStringAttribute("pm.source_context",activeCommand.source_context),otlpStringAttribute("pm.source_context_source",activeCommand.source_context_source),otlpStringAttribute("pm.installation_id",activeCommand.installation_id),otlpStringAttribute("pm.session_id",PROCESS_SESSION_ID),otlpStringAttribute("pm.pm_root_hash",activeCommand.pm_root_hash),otlpStringAttribute("pm.cwd_hash",activeCommand.cwd_hash),otlpBoolAttribute("pm.ok",outcome.ok),otlpIntAttribute("pm.exit_code",normalizedExitCode),otlpIntAttribute("pm.duration_ms",durationMs),otlpStringAttribute("pm.sample_rate",String(sampleRate))];typeof normalizedErrorCode=="string"&&attributes.push(otlpStringAttribute("pm.error_code",normalizedErrorCode)),typeof normalizedErrorCategory=="string"&&attributes.push(otlpStringAttribute("pm.error_category",normalizedErrorCategory)),typeof outcome.error=="string"&&outcome.error.trim().length>0&&attributes.push(otlpStringAttribute("pm.error",sanitizeString(outcome.error)));const payload={resourceSpans:[{resource:{attributes:[otlpStringAttribute("service.name",serviceName)]},scopeSpans:[{scope:{name:"pm-cli.telemetry",version:"1"},spans:[{traceId:activeCommand.otel_trace_id,spanId:activeCommand.otel_span_id,name:`pm.command.${sanitizeString(activeCommand.command)}`,kind:1,startTimeUnixNano:isoToUnixNano(activeCommand.started_at),endTimeUnixNano:isoToUnixNano(finishedAtIso),attributes,status:{code:outcome.ok?1:2,message:outcome.ok?"":sanitizeString(typeof outcome.error=="string"?outcome.error:"command_failed")}}]}]}]};return{endpoint,payload}}function summarizeResult(result,captureLevel="redacted"){if(result==null)return{type:"nullish"};if(typeof result=="string")return{type:"string",value:sanitizeString(result,captureLevel)};if(typeof result=="number"||typeof result=="boolean")return{type:typeof result,value:result};if(Array.isArray(result))return{type:"array",length:result.length,sample:result.slice(0,5).map(entry=>sanitizeValue(entry,void 0,captureLevel))};if(typeof result=="object"){const record=result,keys=Object.keys(record).filter(key=>key!=="tests").sort((left,right)=>left.localeCompare(right)),sanitized={};let previewBytes=0;for(const key of keys.slice(0,25)){const sanitizedValue=sanitizeValue(record[key],key,captureLevel);if(sanitizedValue===void 0)continue;const entrySize=JSON.stringify(sanitizedValue).length;if(previewBytes+entrySize>TELEMETRY_RESULT_PREVIEW_MAX_BYTES){sanitized[key]="[preview_truncated]";break}previewBytes+=entrySize,sanitized[key]=sanitizedValue}return{type:"object",key_count:keys.length,keys_preview:keys.slice(0,50),preview:sanitized}}return{type:typeof result,value:String(result)}}function buildCommandStartPayload(params){const{captureLevel,context,pmVersion,sourceContext,pmRootHash,cwdHash,installationId}=params,commandTaxonomy=deriveTelemetryCommandTaxonomy(context.command),hashedArgs=hashCommandArgs(installationId,context.args),commandInvocationDigest=hashWithInstallationId(installationId,`${context.command}\0${context.args.join("\0")}`),commandOptionsDigest=hashTelemetryValue(installationId,context.options),globalOptionsDigest=hashTelemetryValue(installationId,context.global),authorContextFields=buildAuthorContextPayloadFields(captureLevel,installationId);return captureLevel==="minimal"?{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_args_digest:hashedArgs.digest,command_invocation_digest:commandInvocationDigest,command_options_digest:commandOptionsDigest,global_options_digest:globalOptionsDigest,...authorContextFields}:{pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,...authorContextFields,command_args:sanitizeCommandArgs(context.args,captureLevel),command_args_hashes:hashedArgs.hashes,command_args_digest:hashedArgs.digest,command_invocation_digest:commandInvocationDigest,command_options:sanitizeValue(context.options,void 0,captureLevel),command_options_digest:commandOptionsDigest,global_options:sanitizeValue(context.global,void 0,captureLevel),global_options_digest:globalOptionsDigest,pm_root_hash:pmRootHash,cwd_hash:cwdHash,capture_level:captureLevel,runtime:{node:process.version,platform:process.platform,arch:process.arch,hostname_hash:hashWithInstallationId(installationId,os.hostname()),stdin_tty:process.stdin.isTTY===!0,stdout_tty:process.stdout.isTTY===!0}}}function buildCommandFinishPayload(params){const{captureLevel,pmVersion,sourceContext,outcome,durationMs,startedAt,command,installationId,commandTaxonomy,exitCode,errorCode:errorCode2,errorCategory,commandResolution,resolutionStage}=params,errorFingerprint=outcome.ok===!1?hashTelemetryErrorFingerprint(installationId,command,errorCode2,outcome.error):void 0,authorContextFields=buildAuthorContextPayloadFields(captureLevel,installationId);return captureLevel==="minimal"?{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_resolution:commandResolution,resolution_stage:resolutionStage,ok:outcome.ok,exit_code:exitCode,error_code:errorCode2,error_category:errorCategory,error:outcome.error?sanitizeString(outcome.error,"redacted"):void 0,error_fingerprint:errorFingerprint,duration_ms:durationMs,...authorContextFields}:{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_resolution:commandResolution,resolution_stage:resolutionStage,...authorContextFields,ok:outcome.ok,exit_code:exitCode,error_code:errorCode2,error_category:errorCategory,error:outcome.error?sanitizeString(outcome.error,captureLevel):void 0,error_fingerprint:errorFingerprint,duration_ms:durationMs,started_at:startedAt,result_summary:summarizeResult(outcome.result,captureLevel)}}function buildCommandErrorPayload(params){const{captureLevel,pmVersion,sourceContext,command,commandTaxonomy,commandResolution,resolutionStage,args,options,pmRootHash,cwdHash,installationId,errorCode:errorCode2,errorMessage,errorCategory,exitCode}=params,attemptedArgHashes=hashCommandArgs(installationId,args),attemptedCommandDigest=hashWithInstallationId(installationId,command),attemptedOptionsDigest=hashTelemetryValue(installationId,options),errorFingerprint=hashTelemetryErrorFingerprint(installationId,command,errorCode2,errorMessage),authorContextFields=buildAuthorContextPayloadFields(captureLevel,installationId);return captureLevel==="minimal"?{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_resolution:commandResolution,resolution_stage:resolutionStage,attempted_command_digest:attemptedCommandDigest,attempted_args_digest:attemptedArgHashes.digest,attempted_options_digest:attemptedOptionsDigest,error_code:errorCode2,error_category:errorCategory,exit_code:exitCode,error:sanitizeString(errorMessage,"redacted"),error_fingerprint:errorFingerprint,...authorContextFields}:{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_resolution:commandResolution,resolution_stage:resolutionStage,...authorContextFields,attempted_command:sanitizeString(command,captureLevel),attempted_command_digest:attemptedCommandDigest,attempted_args:sanitizeCommandArgs(args,captureLevel),attempted_args_hashes:attemptedArgHashes.hashes,attempted_args_digest:attemptedArgHashes.digest,attempted_options:sanitizeValue(options,void 0,captureLevel),attempted_options_digest:attemptedOptionsDigest,error_code:errorCode2,error_category:errorCategory,exit_code:exitCode,error:sanitizeString(errorMessage,captureLevel),error_fingerprint:errorFingerprint,pm_root_hash:pmRootHash,cwd_hash:cwdHash,runtime:{node:process.version,platform:process.platform,arch:process.arch,hostname_hash:hashWithInstallationId(installationId,os.hostname()),stdin_tty:process.stdin.isTTY===!0,stdout_tty:process.stdout.isTTY===!0}}}async function ensureInstallationId(globalPmRoot){const settings=await readSettings(globalPmRoot);if(!settings.telemetry.enabled||resolveTelemetryEnvironmentPolicy().telemetry_disabled)return null;if(settings.telemetry.installation_id.trim().length===0){if(isConfigurationOnlySettingsRead(globalPmRoot))return null;settings.telemetry.installation_id=crypto.randomUUID(),await writeSettings(globalPmRoot,settings,"telemetry:install_id")}return{installationId:settings.telemetry.installation_id,endpoint:settings.telemetry.endpoint,retentionDays:Math.max(1,Math.trunc(settings.telemetry.retention_days)),captureLevel:normalizeCaptureLevel(settings.telemetry.capture_level)}}async function appendTelemetryEvent(globalPmRoot,event){let serialized=JSON.stringify({client_schema_version:TELEMETRY_CLIENT_SCHEMA_VERSION,event,attempts:0});if(serialized.length>TELEMETRY_MAX_EVENT_BYTES){const trimmed={...event,payload:{...event.payload,result_summary:{truncated:!0,reason:"payload_size_exceeded",original_bytes:serialized.length}}};serialized=JSON.stringify({client_schema_version:TELEMETRY_CLIENT_SCHEMA_VERSION,event:trimmed,attempts:0})}await appendLineAtomic(queuePath(globalPmRoot),serialized)}async function enqueueTelemetryEvent(globalPmRoot,event){await withQueueMutation(()=>appendTelemetryEvent(globalPmRoot,event),globalPmRoot)}function parseQueueLines(raw){const entries=[];for(const line of raw.split(`
|
|
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]="4b15f41e-4b2a-511a-b2a1-c1c3e3d909c5")}catch{}})();import crypto from"node:crypto";import{spawn}from"node:child_process";import{mkdirSync,rmSync,statSync}from"node:fs";import{mkdir,readdir,rm,stat}from"node:fs/promises";import{request as httpRequest}from"node:http";import{request as httpsRequest}from"node:https";import os from"node:os";import path from"node:path";import{acquireLock}from"../lock/lock.js";import{isActiveCommandUnextended,runWithIsolatedExtensionRuntime}from"../extensions/index.js";import{resolveAutomaticReadSampleRate}from"./read-sampling.js";import{PM_TELEMETRY_SOURCE_CONTEXT_VALUES,isTelemetryTestEnvironment,resolveTelemetryEnvironmentPolicy,resolveTelemetrySourceAttribution}from"./policy.js";import{resolvePmPackageRootFromModule}from"../packages/root.js";import{isFileMissingError,appendLineAtomic,readFileIfExists,writeFileAtomic}from"../fs/fs-utils.js";import{resolveTelemetryErrorCategory}from"../shared/constants.js";import{nowIso}from"../shared/time.js";import{detectAgentIdentity,readAuthorEnvironment}from"../shared/author.js";import{resolveGlobalPmRoot}from"../store/paths.js";import{isConfigurationOnlySettingsRead,readSettings,runWithConfigurationOnlySettings,writeSettings}from"../store/settings.js";import{clearSettingsReadCache}from"../store/settings-read-cache.js";import{deriveTelemetryCommandResolution,deriveTelemetryCommandTaxonomy,inferTelemetryErrorCode}from"./observability.js";const TELEMETRY_QUEUE_RELATIVE_PATH=path.join("runtime","telemetry","events.jsonl"),TELEMETRY_STATE_RELATIVE_PATH=path.join("runtime","telemetry","state.json"),TELEMETRY_OTEL_SPANS_RELATIVE_PATH=path.join("runtime","telemetry","otel-spans.jsonl"),TELEMETRY_OTEL_SPANS_FLUSH_BATCH_SIZE=8,TELEMETRY_OTEL_SPANS_MAX_PENDING=500,TELEMETRY_SCHEMA_VERSION=1,TELEMETRY_CLIENT_SCHEMA_VERSION=1,TELEMETRY_FLUSH_BATCH_SIZE=100,TELEMETRY_MAX_RETRY_DELAY_MS=36e5,TELEMETRY_RETRY_BASE_DELAY_MS=3e4,TELEMETRY_HTTP_TIMEOUT_DEFAULT_MS=2e4,TELEMETRY_HTTP_TIMEOUT_MIN_MS=1e3,TELEMETRY_HTTP_TIMEOUT_MAX_MS=25e3,TELEMETRY_FOREGROUND_LOCK_WAIT_MS=250,MILLISECONDS_PER_DAY=864e5,TELEMETRY_MAX_EVENT_BYTES=65536,TELEMETRY_SANITIZE_MAX_DEPTH=6,TELEMETRY_SANITIZE_MAX_ARRAY_ITEMS=20,TELEMETRY_MAX_QUEUE_ENTRY_ATTEMPTS=15,TELEMETRY_RESULT_PREVIEW_MAX_BYTES=8192,TELEMETRY_QUEUE_REWRITE_RETRY_DELAYS_MS=[25,50,100,200],TELEMETRY_QUEUE_TMP_ORPHAN_MAX_AGE_MS=3600*1e3,TELEMETRY_FLUSH_LOCK_STALE_MS=6e4,TELEMETRY_FLUSH_SPAWN_LOCK_STALE_MS=6e4,OTEL_TRACES_ENDPOINT_ENV="OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",OTEL_BASE_ENDPOINT_ENV="OTEL_EXPORTER_OTLP_ENDPOINT",OTEL_SERVICE_NAME_ENV="OTEL_SERVICE_NAME",PM_TELEMETRY_OTEL_DISABLED_ENV="PM_TELEMETRY_OTEL_DISABLED",PM_TELEMETRY_OTEL_DISABLED_VALUES=new Set(["1","true","yes","on"]),PM_TELEMETRY_INLINE_FLUSH_ENV="PM_TELEMETRY_INLINE_FLUSH",PM_TELEMETRY_FLUSH_CHILD_ENV="PM_TELEMETRY_FLUSH_CHILD",PM_TELEMETRY_HTTP_TIMEOUT_MS_ENV="PM_TELEMETRY_HTTP_TIMEOUT_MS",NATIVE_FETCH=globalThis.fetch;import{PM_TELEMETRY_SOURCE_CONTEXT_VALUES as PM_TELEMETRY_SOURCE_CONTEXT_VALUES2}from"./policy.js";let sourceContextWarningEmitted=!1,_lastFlushPromise=Promise.resolve(),_queueMutationPromise=Promise.resolve();const deferredReadStarts=new WeakMap;async function waitForPendingFlush(){await _lastFlushPromise,await _queueMutationPromise}const BOOLEAN_TRUE_VALUES=new Set(["1","true","yes","on"]),TELEMETRY_HARNESSES=new Set(["claude-code","codex","pi","opencode","cursor","aider","gemini-cli","ci"]),PROCESS_SESSION_ID=crypto.randomUUID(),SENSITIVE_KEYWORDS=["token","secret","password","passwd","api_key","apikey","authorization","cookie","session","credentials","bearer"],REDACTION_INPUT_KEYS=new Set(["literal","literals","regex","regexes","replacement","replacements","setjson","set_json","update"]),SENSITIVE_INLINE_KEY_PATTERN="(?:token|secret|password|passwd|api[_-]?key|apikey|authorization|cookie|session|credentials|bearer|literals?|regex(?:es)?|replacements?)",INLINE_SENSITIVE_ASSIGNMENT_PATTERN=new RegExp(`\\b(${SENSITIVE_INLINE_KEY_PATTERN})\\s*([:=])\\s*([^\\s,;]+)`,"giu"),INLINE_SENSITIVE_FLAG_PATTERN=new RegExp(`(--${SENSITIVE_INLINE_KEY_PATTERN})(=|\\s+)([^\\s,;]+)`,"giu"),ABSOLUTE_PATH_TOKEN_PATTERN=/(^|[\s"'`(=])\/(?:[^\s"'`),;]+)/g,BEARER_TOKEN_PATTERN=/bearer\s+[a-z0-9._=-]+/giu,PRIVATE_IP_PATTERN=/\b(?:10\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|172\.(?:1[6-9]|2\d|3[01])\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)|192\.168\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.(?:25[0-5]|2[0-4]\d|[01]?\d?\d))\b/g;function queuePath(globalPmRoot){return path.join(globalPmRoot,TELEMETRY_QUEUE_RELATIVE_PATH)}function otelSpansQueuePath(globalPmRoot){return path.join(globalPmRoot,TELEMETRY_OTEL_SPANS_RELATIVE_PATH)}function telemetryRuntimeDirectory(globalPmRoot){return path.dirname(queuePath(globalPmRoot))}function runtimeStatePath(globalPmRoot){return path.join(globalPmRoot,TELEMETRY_STATE_RELATIVE_PATH)}function flushLockPath(globalPmRoot){return path.join(globalPmRoot,"runtime","telemetry","flush.lock")}function flushSpawnLockPath(globalPmRoot){return path.join(globalPmRoot,"runtime","telemetry","flush.spawn.lock")}function telemetryFlushRunnerPath(){return path.join(resolvePmPackageRootFromModule(import.meta.url,["../../.."]),"dist","cli","telemetry-flush.js")}function shouldFlushInline(){return parseBooleanTrueLike(process.env[PM_TELEMETRY_INLINE_FLUSH_ENV])||parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV])?!0:isTelemetryTestEnvironment()}async function readRuntimeState(globalPmRoot){const raw=await readFileIfExists(runtimeStatePath(globalPmRoot));if(!raw||raw.trim().length===0)return{};try{const parsed=JSON.parse(raw);return typeof parsed!="object"||parsed===null||Array.isArray(parsed)?{}:parsed}catch{return{}}}async function writeRuntimeState(globalPmRoot,patch){try{await withQueueMutation(async()=>{const next={...await readRuntimeState(globalPmRoot),...patch},normalized=Object.fromEntries(Object.entries(next).filter(([,value])=>value!==void 0).sort((left,right)=>left[0].localeCompare(right[0])));await writeFileAtomic(runtimeStatePath(globalPmRoot),`${JSON.stringify(normalized,null,2)}
|
|
2
|
+
`,{createParentDirectories:!parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV])})},globalPmRoot)}catch{}}function isSensitiveKey(key){const normalized=key.trim().toLowerCase().replaceAll("-","_").replaceAll(/[^a-z0-9_]+/g,"_"),tokens=normalized.split("_").filter(token=>token.length>0);return REDACTION_INPUT_KEYS.has(normalized)||SENSITIVE_KEYWORDS.some(keyword=>normalized===keyword||normalized.endsWith(`_${keyword}`)||tokens.includes(keyword))}function redactInlineSensitiveAssignments(input){return input.replaceAll(INLINE_SENSITIVE_ASSIGNMENT_PATTERN,(_match,key,delimiter)=>`${key}${delimiter}[redacted]`).replaceAll(INLINE_SENSITIVE_FLAG_PATTERN,(_match,flag,delimiter)=>`${flag}${delimiter}[redacted]`)}function redactAbsolutePathTokens(input){return input.replaceAll(ABSOLUTE_PATH_TOKEN_PATTERN,(_match,prefix)=>`${prefix}[redacted_path]`)}function isAsciiLetterOrDigitCode(code){const isUpper=code>=65&&code<=90,isLower=code>=97&&code<=122,isDigit=code>=48&&code<=57;return isUpper||isLower||isDigit}function isEmailLocalCharacter(character){if(!character)return!1;const code=character.charCodeAt(0);return isAsciiLetterOrDigitCode(code)?!0:character==="."||character==="_"||character==="%"||character==="+"||character==="-"}function isEmailDomainCharacter(character){if(!character)return!1;const code=character.charCodeAt(0);return isAsciiLetterOrDigitCode(code)?!0:character==="."||character==="-"}function looksLikeEmailToken(token){const atIndex=token.indexOf("@");if(atIndex<=0||atIndex!==token.lastIndexOf("@")||atIndex===token.length-1)return!1;const localPart=token.slice(0,atIndex),domainPart=token.slice(atIndex+1),lastDot=domainPart.lastIndexOf(".");if(lastDot<=0||lastDot===domainPart.length-1||domainPart.length-(lastDot+1)<2)return!1;for(const character of localPart)if(!isEmailLocalCharacter(character))return!1;for(const character of domainPart)if(!isEmailDomainCharacter(character))return!1;return!0}function redactEmailTokens(input){let redacted="",cursor=0;for(;cursor<input.length;){const atIndex=input.indexOf("@",cursor);if(atIndex<0){redacted+=input.slice(cursor);break}let start=atIndex-1;for(;start>=cursor&&isEmailLocalCharacter(input[start]);)start-=1;start+=1;let end=atIndex+1;for(;end<input.length&&isEmailDomainCharacter(input[end]);)end+=1;const candidate=input.slice(start,end);if(looksLikeEmailToken(candidate)){redacted+=input.slice(cursor,start),redacted+="[redacted_email]",cursor=end;continue}redacted+=input.slice(cursor,atIndex+1),cursor=atIndex+1}return redacted}function sanitizeCommonSensitiveTokens(input){return redactEmailTokens(input).replaceAll(BEARER_TOKEN_PATTERN,"bearer [redacted_token]").replaceAll(PRIVATE_IP_PATTERN,"[redacted_ip]")}function sanitizeStringRedacted(input){const withoutCommonSensitiveTokens=sanitizeCommonSensitiveTokens(input),withoutInlineSecrets=redactInlineSensitiveAssignments(withoutCommonSensitiveTokens),withoutAbsolutePaths=redactAbsolutePathTokens(withoutInlineSecrets),trimmed=withoutAbsolutePaths.trim();return trimmed.startsWith("/")&&trimmed.length>1?"[redacted_path]":withoutAbsolutePaths.length>512?`${withoutAbsolutePaths.slice(0,509)}...`:withoutAbsolutePaths}function sanitizeStringMax(input){const withoutCommonSensitiveTokens=sanitizeCommonSensitiveTokens(input),withoutInlineSecrets=redactInlineSensitiveAssignments(withoutCommonSensitiveTokens),withoutAbsolutePaths=redactAbsolutePathTokens(withoutInlineSecrets),trimmed=withoutAbsolutePaths.trim();return trimmed.startsWith("/")&&trimmed.length>1?"[redacted_path]":withoutAbsolutePaths.length>2048?`${withoutAbsolutePaths.slice(0,2045)}...`:withoutAbsolutePaths}function sanitizeString(input,captureLevel="redacted"){return captureLevel==="max"?sanitizeStringMax(input):sanitizeStringRedacted(input)}function sanitizeValue(value,keyHint,captureLevel="redacted",depth=0){if(keyHint&&isSensitiveKey(keyHint))return"[redacted]";if(value==null)return value;if(typeof value=="string")return sanitizeString(value,captureLevel);if(typeof value=="number"||typeof value=="boolean")return value;if(depth>=TELEMETRY_SANITIZE_MAX_DEPTH)return"[depth_truncated]";if(Array.isArray(value))return value.slice(0,TELEMETRY_SANITIZE_MAX_ARRAY_ITEMS).map(entry=>sanitizeValue(entry,void 0,captureLevel,depth+1));if(typeof value=="object"){const record=value,sanitized={};for(const[key,nested]of Object.entries(record))sanitized[key]=sanitizeValue(nested,key,captureLevel,depth+1);return sanitized}return String(value)}function sanitizeCommandArgs(args,captureLevel="redacted"){const sanitized=[];let nextIsSensitiveValue=!1;for(const rawArg of args){const arg=sanitizeString(rawArg,captureLevel);if(nextIsSensitiveValue){sanitized.push("[redacted]"),nextIsSensitiveValue=!1;continue}if(arg.startsWith("--")){const withoutPrefix=arg.slice(2),delimiterIndex=withoutPrefix.indexOf("=");if(delimiterIndex>=0){const key=withoutPrefix.slice(0,delimiterIndex),value=withoutPrefix.slice(delimiterIndex+1);isSensitiveKey(key)?sanitized.push(`--${key}=[redacted]`):sanitized.push(`--${key}=${sanitizeString(value,captureLevel)}`);continue}if(isSensitiveKey(withoutPrefix)){sanitized.push(`--${withoutPrefix}`),nextIsSensitiveValue=!0;continue}}sanitized.push(arg)}return sanitized}function normalizeCaptureLevel(value){const normalized=value?.trim().toLowerCase();return normalized==="minimal"||normalized==="redacted"||normalized==="max"?normalized:"redacted"}function parseBooleanTrueLike(value){return BOOLEAN_TRUE_VALUES.has((value??"").trim().toLowerCase())}function resolveTelemetryHttpTimeoutMs(){const rawConfigured=process.env[PM_TELEMETRY_HTTP_TIMEOUT_MS_ENV]?.trim();if(!rawConfigured)return TELEMETRY_HTTP_TIMEOUT_DEFAULT_MS;const configured=Number(rawConfigured);return Number.isFinite(configured)?Math.min(TELEMETRY_HTTP_TIMEOUT_MAX_MS,Math.max(TELEMETRY_HTTP_TIMEOUT_MIN_MS,Math.trunc(configured))):TELEMETRY_HTTP_TIMEOUT_DEFAULT_MS}async function postTelemetryJson(endpoint,headers,body){const url=new URL(endpoint);if(globalThis.fetch!==NATIVE_FETCH){const controller=new AbortController;let timeout;const deadline=new Promise((_resolve,reject)=>{timeout=setTimeout(()=>{controller.abort(),reject(new Error("telemetry_http_timeout"))},resolveTelemetryHttpTimeoutMs())});try{return(await Promise.race([globalThis.fetch(endpoint,{method:"POST",headers,body,signal:controller.signal}),deadline])).status}finally{clearTimeout(timeout)}}const request=url.protocol==="https:"?httpsRequest:url.protocol==="http:"?httpRequest:void 0;if(!request)throw new Error(`telemetry_http_protocol_unsupported_${url.protocol}`);return new Promise((resolve,reject)=>{const timeoutMs=resolveTelemetryHttpTimeoutMs(),requestOptions={method:"POST",headers:{...headers,"content-length":Buffer.byteLength(body)},signal:AbortSignal.timeout(timeoutMs),autoSelectFamilyAttemptTimeout:Math.min(5e3,timeoutMs)},clientRequest=request(url,requestOptions,response=>{response.once("error",reject),response.once("end",()=>resolve(response.statusCode)),response.resume()});clientRequest.once("error",reject),clientRequest.end(body)})}function normalizePmVersion(value){const trimmed=typeof value=="string"?value.trim():"";return trimmed.length>0?trimmed:"0.0.0"}function normalizeTelemetryErrorCode(value){const normalized=value?.trim();return normalized&&normalized.length>0?normalized:void 0}function normalizeTelemetryExitCode(exitCode,ok){return Number.isFinite(exitCode)?Math.max(0,Math.trunc(exitCode)):ok?0:1}function normalizeTelemetryErrorCategory(params){if(!params.ok)return typeof params.errorCategory=="string"&¶ms.errorCategory.trim().length>0?params.errorCategory:typeof params.errorCode=="string"&¶ms.errorCode.trim().length>0?resolveTelemetryErrorCategory(params.errorCode):"unknown"}function resolveTelemetrySourceContext(globalOptions){const resolved=resolveTelemetrySourceAttribution(globalOptions);return resolved.source_context_source==="env_override_rejected"&&!sourceContextWarningEmitted&&!globalOptions.quiet&&(sourceContextWarningEmitted=!0,process.stderr.write(`[pm] warning: PM_TELEMETRY_SOURCE_CONTEXT is not one of ${PM_TELEMETRY_SOURCE_CONTEXT_VALUES.join("|")}; ignoring override.
|
|
3
|
+
`)),resolved}function hashWithInstallationId(installationId,value){return crypto.createHash("sha256").update(`${installationId}:${value}`).digest("hex")}function buildAuthorContextPayloadFields(captureLevel,installationId){const author=(readAuthorEnvironment()??"").trim(),agent=detectAgentIdentity({env:process.env,argv:process.argv}),hasAgentContext=agent.harness!==void 0||agent.model!==void 0;return captureLevel==="minimal"?{has_author_context:author.length>0,has_agent_context:hasAgentContext}:{agent_harness:agent.harness?TELEMETRY_HARNESSES.has(agent.harness)?agent.harness:"other":"none",ci:parseBooleanTrueLike(process.env.CI),...author.length>0?{author_context_hash:hashWithInstallationId(installationId,author)}:{},...agent.harness?{agent_harness_hash:hashWithInstallationId(installationId,agent.harness)}:{},...agent.model?{agent_model_hash:hashWithInstallationId(installationId,agent.model)}:{},...agent.model_source?{agent_model_source:agent.model_source}:{}}}function normalizeForHash(value,depth=0){if(value==null||typeof value=="string"||typeof value=="number"||typeof value=="boolean")return value;if(depth>=TELEMETRY_SANITIZE_MAX_DEPTH)return"[depth_truncated]";if(Array.isArray(value))return value.slice(0,TELEMETRY_SANITIZE_MAX_ARRAY_ITEMS).map(entry=>normalizeForHash(entry,depth+1));if(typeof value=="object"){const record=value,normalized={},sortedKeys=Object.keys(record).sort((left,right)=>left.localeCompare(right));for(const key of sortedKeys)normalized[key]=normalizeForHash(record[key],depth+1);return normalized}return String(value)}function hashTelemetryValue(installationId,value){return hashWithInstallationId(installationId,JSON.stringify(normalizeForHash(value)))}function hashCommandArgs(installationId,args){return{hashes:args.map(arg=>hashWithInstallationId(installationId,arg)),digest:hashWithInstallationId(installationId,args.join("\0"))}}function hashTelemetryErrorFingerprint(installationId,command,errorCode2,errorMessage){const normalizedMessage=sanitizeString(typeof errorMessage=="string"?errorMessage:"","redacted"),normalizedCode=typeof errorCode2=="string"&&errorCode2.length>0?errorCode2:"unknown_error",fingerprintSource=`${command}\0${normalizedCode}\0${normalizedMessage}`;return hashWithInstallationId(installationId,fingerprintSource)}function resolveOtelTracesEndpoint(){if(PM_TELEMETRY_OTEL_DISABLED_VALUES.has((process.env[PM_TELEMETRY_OTEL_DISABLED_ENV]??"").trim().toLowerCase()))return null;const directEndpoint=(process.env[OTEL_TRACES_ENDPOINT_ENV]??"").trim();if(directEndpoint.length>0)try{return new URL(directEndpoint).toString()}catch{return null}const baseEndpoint=(process.env[OTEL_BASE_ENDPOINT_ENV]??"").trim();if(baseEndpoint.length===0)return null;try{const url=new URL(baseEndpoint),normalizedPath=url.pathname.replace(/\/+$/,"");return normalizedPath.endsWith("/v1/traces")||(url.pathname=`${normalizedPath.length===0?"":normalizedPath}/v1/traces`),url.toString()}catch{return null}}function isoToUnixNano(iso){const parsedMs=Date.parse(iso),epochMs=Number.isNaN(parsedMs)?Date.now():parsedMs;return`${BigInt(epochMs)*1000000n}`}function otlpStringAttribute(key,value){return{key,value:{stringValue:value}}}function otlpBoolAttribute(key,value){return{key,value:{boolValue:value}}}function otlpIntAttribute(key,value){return{key,value:{intValue:String(Math.max(0,Math.trunc(value)))}}}function buildOtelSpanRequest(activeCommand,outcome,finishedAtIso,durationMs,sampleRate=1){const endpoint=activeCommand.otel_traces_endpoint;if(typeof endpoint!="string"||endpoint.trim().length===0||[activeCommand.otel_trace_id,activeCommand.otel_span_id].some(id=>typeof id!="string"||id.length===0))return null;const serviceNameCandidate=sanitizeString((process.env[OTEL_SERVICE_NAME_ENV]??"").trim()),serviceName=serviceNameCandidate.length>0?serviceNameCandidate:"pm-cli",normalizedExitCode=normalizeTelemetryExitCode(outcome.exit_code,outcome.ok),normalizedErrorCode=normalizeTelemetryErrorCode(outcome.error_code),normalizedErrorCategory=normalizeTelemetryErrorCategory({ok:outcome.ok,errorCode:normalizedErrorCode,errorCategory:outcome.error_category}),attributes=[otlpStringAttribute("pm.command",sanitizeString(activeCommand.command)),otlpStringAttribute("pm.version",activeCommand.pm_version),otlpStringAttribute("pm.source_context",activeCommand.source_context),otlpStringAttribute("pm.source_context_source",activeCommand.source_context_source),otlpStringAttribute("pm.installation_id",activeCommand.installation_id),otlpStringAttribute("pm.session_id",PROCESS_SESSION_ID),otlpStringAttribute("pm.pm_root_hash",activeCommand.pm_root_hash),otlpStringAttribute("pm.cwd_hash",activeCommand.cwd_hash),otlpBoolAttribute("pm.ok",outcome.ok),otlpIntAttribute("pm.exit_code",normalizedExitCode),otlpIntAttribute("pm.duration_ms",durationMs),otlpStringAttribute("pm.sample_rate",String(sampleRate))];typeof normalizedErrorCode=="string"&&attributes.push(otlpStringAttribute("pm.error_code",normalizedErrorCode)),typeof normalizedErrorCategory=="string"&&attributes.push(otlpStringAttribute("pm.error_category",normalizedErrorCategory)),typeof outcome.error=="string"&&outcome.error.trim().length>0&&attributes.push(otlpStringAttribute("pm.error",sanitizeString(outcome.error)));const payload={resourceSpans:[{resource:{attributes:[otlpStringAttribute("service.name",serviceName)]},scopeSpans:[{scope:{name:"pm-cli.telemetry",version:"1"},spans:[{traceId:activeCommand.otel_trace_id,spanId:activeCommand.otel_span_id,name:`pm.command.${sanitizeString(activeCommand.command)}`,kind:1,startTimeUnixNano:isoToUnixNano(activeCommand.started_at),endTimeUnixNano:isoToUnixNano(finishedAtIso),attributes,status:{code:outcome.ok?1:2,message:outcome.ok?"":sanitizeString(typeof outcome.error=="string"?outcome.error:"command_failed")}}]}]}]};return{endpoint,payload}}function summarizeResult(result,captureLevel="redacted"){if(result==null)return{type:"nullish"};if(typeof result=="string")return{type:"string",value:sanitizeString(result,captureLevel)};if(typeof result=="number"||typeof result=="boolean")return{type:typeof result,value:result};if(Array.isArray(result))return{type:"array",length:result.length,sample:result.slice(0,5).map(entry=>sanitizeValue(entry,void 0,captureLevel))};if(typeof result=="object"){const record=result,keys=Object.keys(record).filter(key=>key!=="tests").sort((left,right)=>left.localeCompare(right)),sanitized={};let previewBytes=0;for(const key of keys.slice(0,25)){const sanitizedValue=sanitizeValue(record[key],key,captureLevel);if(sanitizedValue===void 0)continue;const entrySize=JSON.stringify(sanitizedValue).length;if(previewBytes+entrySize>TELEMETRY_RESULT_PREVIEW_MAX_BYTES){sanitized[key]="[preview_truncated]";break}previewBytes+=entrySize,sanitized[key]=sanitizedValue}return{type:"object",key_count:keys.length,keys_preview:keys.slice(0,50),preview:sanitized}}return{type:typeof result,value:String(result)}}function buildCommandStartPayload(params){const{captureLevel,context,pmVersion,sourceContext,pmRootHash,cwdHash,installationId}=params,commandTaxonomy=deriveTelemetryCommandTaxonomy(context.command),hashedArgs=hashCommandArgs(installationId,context.args),commandInvocationDigest=hashWithInstallationId(installationId,`${context.command}\0${context.args.join("\0")}`),commandOptionsDigest=hashTelemetryValue(installationId,context.options),globalOptionsDigest=hashTelemetryValue(installationId,context.global),authorContextFields=buildAuthorContextPayloadFields(captureLevel,installationId);return captureLevel==="minimal"?{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_args_digest:hashedArgs.digest,command_invocation_digest:commandInvocationDigest,command_options_digest:commandOptionsDigest,global_options_digest:globalOptionsDigest,...authorContextFields}:{pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,...authorContextFields,command_args:sanitizeCommandArgs(context.args,captureLevel),command_args_hashes:hashedArgs.hashes,command_args_digest:hashedArgs.digest,command_invocation_digest:commandInvocationDigest,command_options:sanitizeValue(context.options,void 0,captureLevel),command_options_digest:commandOptionsDigest,global_options:sanitizeValue(context.global,void 0,captureLevel),global_options_digest:globalOptionsDigest,pm_root_hash:pmRootHash,cwd_hash:cwdHash,capture_level:captureLevel,runtime:{node:process.version,platform:process.platform,arch:process.arch,hostname_hash:hashWithInstallationId(installationId,os.hostname()),stdin_tty:process.stdin.isTTY===!0,stdout_tty:process.stdout.isTTY===!0}}}function buildCommandFinishPayload(params){const{captureLevel,pmVersion,sourceContext,outcome,durationMs,startedAt,command,installationId,commandTaxonomy,exitCode,errorCode:errorCode2,errorCategory,commandResolution,resolutionStage}=params,errorFingerprint=outcome.ok===!1?hashTelemetryErrorFingerprint(installationId,command,errorCode2,outcome.error):void 0,authorContextFields=buildAuthorContextPayloadFields(captureLevel,installationId);return captureLevel==="minimal"?{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_resolution:commandResolution,resolution_stage:resolutionStage,ok:outcome.ok,exit_code:exitCode,error_code:errorCode2,error_category:errorCategory,error:outcome.error?sanitizeString(outcome.error,"redacted"):void 0,error_fingerprint:errorFingerprint,duration_ms:durationMs,...authorContextFields}:{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_resolution:commandResolution,resolution_stage:resolutionStage,...authorContextFields,ok:outcome.ok,exit_code:exitCode,error_code:errorCode2,error_category:errorCategory,error:outcome.error?sanitizeString(outcome.error,captureLevel):void 0,error_fingerprint:errorFingerprint,duration_ms:durationMs,started_at:startedAt,result_summary:summarizeResult(outcome.result,captureLevel)}}function buildCommandErrorPayload(params){const{captureLevel,pmVersion,sourceContext,command,commandTaxonomy,commandResolution,resolutionStage,args,options,pmRootHash,cwdHash,installationId,errorCode:errorCode2,errorMessage,errorCategory,exitCode}=params,attemptedArgHashes=hashCommandArgs(installationId,args),attemptedCommandDigest=hashWithInstallationId(installationId,command),attemptedOptionsDigest=hashTelemetryValue(installationId,options),errorFingerprint=hashTelemetryErrorFingerprint(installationId,command,errorCode2,errorMessage),authorContextFields=buildAuthorContextPayloadFields(captureLevel,installationId);return captureLevel==="minimal"?{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_resolution:commandResolution,resolution_stage:resolutionStage,attempted_command_digest:attemptedCommandDigest,attempted_args_digest:attemptedArgHashes.digest,attempted_options_digest:attemptedOptionsDigest,error_code:errorCode2,error_category:errorCategory,exit_code:exitCode,error:sanitizeString(errorMessage,"redacted"),error_fingerprint:errorFingerprint,...authorContextFields}:{capture_level:captureLevel,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,command_taxonomy:commandTaxonomy,command_resolution:commandResolution,resolution_stage:resolutionStage,...authorContextFields,attempted_command:sanitizeString(command,captureLevel),attempted_command_digest:attemptedCommandDigest,attempted_args:sanitizeCommandArgs(args,captureLevel),attempted_args_hashes:attemptedArgHashes.hashes,attempted_args_digest:attemptedArgHashes.digest,attempted_options:sanitizeValue(options,void 0,captureLevel),attempted_options_digest:attemptedOptionsDigest,error_code:errorCode2,error_category:errorCategory,exit_code:exitCode,error:sanitizeString(errorMessage,captureLevel),error_fingerprint:errorFingerprint,pm_root_hash:pmRootHash,cwd_hash:cwdHash,runtime:{node:process.version,platform:process.platform,arch:process.arch,hostname_hash:hashWithInstallationId(installationId,os.hostname()),stdin_tty:process.stdin.isTTY===!0,stdout_tty:process.stdout.isTTY===!0}}}async function ensureInstallationId(globalPmRoot){const settings=await readSettings(globalPmRoot);if(!settings.telemetry.enabled||resolveTelemetryEnvironmentPolicy().telemetry_disabled)return null;if(settings.telemetry.installation_id.trim().length===0){if(isConfigurationOnlySettingsRead(globalPmRoot))return null;settings.telemetry.installation_id=crypto.randomUUID(),await writeSettings(globalPmRoot,settings,"telemetry:install_id")}return{installationId:settings.telemetry.installation_id,endpoint:settings.telemetry.endpoint,retentionDays:Math.max(1,Math.trunc(settings.telemetry.retention_days)),captureLevel:normalizeCaptureLevel(settings.telemetry.capture_level)}}async function appendTelemetryEvent(globalPmRoot,event){let serialized=JSON.stringify({client_schema_version:TELEMETRY_CLIENT_SCHEMA_VERSION,event,attempts:0});if(serialized.length>TELEMETRY_MAX_EVENT_BYTES){const trimmed={...event,payload:{...event.payload,result_summary:{truncated:!0,reason:"payload_size_exceeded",original_bytes:serialized.length}}};serialized=JSON.stringify({client_schema_version:TELEMETRY_CLIENT_SCHEMA_VERSION,event:trimmed,attempts:0})}await appendLineAtomic(queuePath(globalPmRoot),serialized)}async function enqueueTelemetryEvent(globalPmRoot,event){await withQueueMutation(()=>appendTelemetryEvent(globalPmRoot,event),globalPmRoot)}function parseQueueLines(raw){const entries=[];for(const line of raw.split(`
|
|
4
4
|
`)){const trimmed=line.trim();if(trimmed.length!==0)try{const parsed=JSON.parse(trimmed);parsed&&typeof parsed=="object"&&parsed.event&&typeof parsed.event=="object"&&typeof parsed.attempts=="number"&&(parsed.client_schema_version===void 0||typeof parsed.client_schema_version=="number"&&Number.isFinite(parsed.client_schema_version))&&entries.push(parsed)}catch{}}return entries}function nextRetryIso(attempts){const delay=Math.min(TELEMETRY_RETRY_BASE_DELAY_MS*2**Math.max(attempts-1,0),TELEMETRY_MAX_RETRY_DELAY_MS);return new Date(Date.now()+delay).toISOString()}function isDueForRetryAt(nextAttemptAfter){if(typeof nextAttemptAfter!="string"||nextAttemptAfter.trim().length===0)return!0;const dueAtMs=Date.parse(nextAttemptAfter);return Number.isNaN(dueAtMs)?!0:dueAtMs<=Date.now()}function isDueForRetry(entry){return isDueForRetryAt(entry.next_attempt_after)}function retentionCutoffMs(retentionDays){const normalizedDays=Number.isFinite(retentionDays)?Math.max(1,Math.trunc(retentionDays)):1;return Date.now()-normalizedDays*MILLISECONDS_PER_DAY}function isExpiredQueueEntry(entry,cutoffMs){const occurredAt=entry.event?.occurred_at;if(typeof occurredAt!="string"||occurredAt.trim().length===0)return!1;const occurredAtMs=Date.parse(occurredAt);return Number.isNaN(occurredAtMs)?!1:occurredAtMs<cutoffMs}function pruneExpiredQueueEntries(entries,retentionDays){const cutoffMs=retentionCutoffMs(retentionDays),retained=[];let prunedCount=0;for(const entry of entries){if(JSON.stringify(entry).length>TELEMETRY_MAX_EVENT_BYTES||isExpiredQueueEntry(entry,cutoffMs)||entry.attempts>=TELEMETRY_MAX_QUEUE_ENTRY_ATTEMPTS){prunedCount+=1;continue}retained.push(entry)}return{entries:retained,prunedCount}}async function rewriteQueue(globalPmRoot,entries){const serialized=entries.map(entry=>JSON.stringify(entry)).join(`
|
|
5
5
|
`),contents=serialized.length>0?`${serialized}
|
|
6
6
|
`:"";for(let attempt=0;;attempt+=1)try{await writeFileAtomic(queuePath(globalPmRoot),contents,{createParentDirectories:!parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV])});return}catch(error){const retryDelay=TELEMETRY_QUEUE_REWRITE_RETRY_DELAYS_MS[attempt];if(retryDelay===void 0||!isRetryableQueueRewriteError(error))throw error;await sleep(retryDelay)}}function isRetryableQueueRewriteError(error){if(typeof error!="object"||error===null||!("code"in error))return!1;const code=error.code;return code==="EACCES"||code==="EBUSY"||code==="EPERM"}function sleep(milliseconds){return new Promise(resolve=>{setTimeout(resolve,milliseconds)})}async function appendPendingOtelSpan(globalPmRoot,request){const pending={id:crypto.randomUUID(),endpoint:request.endpoint,payload:request.payload,enqueued_at:nowIso(),attempts:0},serialized=JSON.stringify(pending);serialized.length>TELEMETRY_MAX_EVENT_BYTES||await appendLineAtomic(otelSpansQueuePath(globalPmRoot),serialized)}async function enqueuePendingOtelSpan(globalPmRoot,request){await withQueueMutation(()=>appendPendingOtelSpan(globalPmRoot,request),globalPmRoot)}function backfillPendingOtelSpanId(entry){const material=JSON.stringify([entry.endpoint,entry.enqueued_at,entry.payload]);return crypto.createHash("sha256").update(material).digest("hex").slice(0,32)}function parsePendingOtelSpanLines(raw){const entries=[];for(const line of raw.split(`
|
|
@@ -4,6 +4,21 @@ export declare function resolveLifecycleVerbRecovery(verb:string,availablePaths:
|
|
|
4
4
|
examples:string[][];
|
|
5
5
|
nextSteps:string[];
|
|
6
6
|
} | undefined;
|
|
7
|
+
/** Completeness controls one read command declares, derived from its read-output surface and flag contracts. */
|
|
8
|
+
export interface ReadCompletenessControls {
|
|
9
|
+
/** Canonical read-output surface. */
|
|
10
|
+
command:string;
|
|
11
|
+
/** Projection modes the command spells as boolean `--<mode>` flags. */
|
|
12
|
+
modes:string[];
|
|
13
|
+
/** Closed `--depth` value domain, empty when the command declares no detail depth. */
|
|
14
|
+
depth_values:string[];
|
|
15
|
+
/** Every declared flag spelling, used to refuse corrections for options the command already accepts. */
|
|
16
|
+
declared_flags:string[];
|
|
17
|
+
}
|
|
18
|
+
/** Resolve the completeness spellings a read command accepts, so recovery never guesses from another command's vocabulary. */
|
|
19
|
+
export declare function resolveReadCompletenessControls(commandName:string):ReadCompletenessControls | undefined;
|
|
20
|
+
/** Render one command's completeness controls as the flags an agent can type on that same command. */
|
|
21
|
+
export declare function describeReadCompletenessControls(controls:ReadCompletenessControls):string;
|
|
7
22
|
/** Derive a same-command read retry for known completeness and encoding mistakes without discarding intent. */
|
|
8
23
|
export declare function resolveReadOptionRetryArgs(commandName:string,invocationArgv:readonly string[],unknownOption:string):string[] | undefined;
|
|
9
24
|
/** Identify presentation intent that must not be silently dropped from an unknown-option retry. */
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="682c27fa-94d8-529b-92fc-ac8a2eb7e138")}catch{}})();import{renderPmCommand}from"../command-line.js";import{resolveLinkedResourcePositionalRecovery}from"./linked-resource-recovery.js";import{resolveSubcommandFlagContractsForCommand}from"../cli-contracts/flag-contracts.js";import{findBootstrapCommandTokenIndex,parseBootstrapCommandName}from"../cli-contracts/bootstrap-command-scanner.js";import{READ_OUTPUT_DIMENSION_FLAGS,READ_OUTPUT_COMPOSITION_FLAGS}from"../read-output/options.js";import{resolvePmCommandOperation}from"../cli-contracts/command-aliases.js";import{readOutputIncludeModeOptionsForSurface,resolveNativeReadOutputSurface}from"../read-output/surfaces.js";const READ_PROJECTION_FLAGS=new Set([...Object.values(READ_OUTPUT_DIMENSION_FLAGS),...READ_OUTPUT_COMPOSITION_FLAGS,"--full","--brief","--compact","--summary","--fields","--section","--token-budget"]),MUTATION_RECEIPT_FLAGS=new Set(["--full-changed-fields","--no-changed-fields","--id-only"]);function resolveLifecycleVerbRecovery(verb,availablePaths){if(!["block","unblock"].includes(verb)||availablePaths.includes(verb)||!availablePaths.includes("update"))return;const flags=new Set(resolveSubcommandFlagContractsForCommand("update").map(entry=>entry.flag));if((verb==="block"?["--blocked-by","--blocked-reason"]:["--unset","--unblock-note"]).every(flag=>flags.has(flag)))return verb==="block"?{examples:[["update","<item-id>","--blocked-by","<blocker-id>","--blocked-reason","<reason>"]],nextSteps:["Choose the actual item and blocker identifiers before running update. --blocked-by records the blocker field and its blocked_by relationship."]}:{examples:[["update","<item-id>","--unset","blocked-by","--unset","blocked-reason","--unblock-note","<note>"]],nextSteps:["Inspect the item's blockers before running update. --unset blocked-by removes the blocker field and all blocked_by relationships; --unset blocked-reason clears the stale reason. --unblock-note alone records a note and does not unblock the item.","If your project also uses a blocked lifecycle status, choose its appropriate next status separately with update --status."]}}function activitySinceCorrection(token,next){const inline=token.includes("="),value=inline?token.slice(token.indexOf("=")+1):next;if(!(!value||value.startsWith("--")))return{consumed:inline?1:2,replacement:["--from",value],conflicts:["--from"]}}const COMPLETENESS_CONFLICT_FLAGS=["--depth","--output-include","--fields","--section","--for"];function resolveReadCompletenessControls(commandName){const surface=resolveNativeReadOutputSurface(resolvePmCommandOperation(commandName.trim().toLowerCase()));if(surface===void 0)return;const flags=resolveSubcommandFlagContractsForCommand(surface),declared=flags.flatMap(entry=>[entry.flag,...entry.aliases??[]]),modes=[...readOutputIncludeModeOptionsForSurface(surface).keys()].filter(mode=>declared.includes(`--${mode}`)),depthValues=[...flags.find(entry=>entry.flag==="--depth")?.values??[]];if(!(modes.length===0&&depthValues.length===0))return{command:surface,modes,depth_values:depthValues,declared_flags:declared}}function describeReadCompletenessControls(controls){return[...controls.depth_values.length>0?[`--depth ${controls.depth_values.join("|")}`]:[],...controls.modes.map(mode=>`--${mode}`)].join(", ")}function completenessCorrection(command,flag,token,next){const controls=resolveReadCompletenessControls(command);if(controls===void 0||controls.declared_flags.includes(flag))return;const conflicts=[...COMPLETENESS_CONFLICT_FLAGS,...controls.modes.map(mode=>`--${mode}`)].filter(entry=>entry!==flag);if(flag==="--depth"){const inline=token.includes("="),value=(inline?token.slice(token.indexOf("=")+1):next)?.trim().toLowerCase();if(!value)return;const consumed=inline?1:2;return controls.modes.includes(value)?{consumed,replacement:[`--${value}`],conflicts}:value==="standard"?{consumed,replacement:[],conflicts}:void 0}const level=flag.slice(2);return token===flag&&controls.depth_values.includes(level)?{consumed:1,replacement:["--depth",level],conflicts}:void 0}function readOptionCorrection(command,flag,token,next){return flag==="--since"&&command==="activity"?activitySinceCorrection(token,next):flag==="--toon"&&token===flag?{consumed:1,replacement:["--output-format","toon"],conflicts:["--json","--format","--output-format","--stream"]}:completenessCorrection(command,flag,token,next)}function resolveInvokedCommand(argv){const index=findBootstrapCommandTokenIndex(argv);if(index===void 0)return;const root=argv[index].trim().toLowerCase(),path=`${root} ${argv[index+1]?.trim().toLowerCase()??""}`,namespaced=resolvePmCommandOperation(path);return namespaced!==path.trim()?namespaced:root==="ctx"?"context":resolvePmCommandOperation(root)}function resolveReadOptionRetryArgs(commandName,invocationArgv,unknownOption){const command=commandName==="ctx"?"context":resolvePmCommandOperation(commandName);if(resolveNativeReadOutputSurface(command)===void 0||invocationArgv.includes("--")||resolveInvokedCommand(invocationArgv)!==command)return;const flag=unknownOption.split("=",1)[0],indices=invocationArgv.flatMap((token,index2)=>token===flag||token.startsWith(`${flag}=`)?[index2]:[]);if(indices.length!==1)return;const index=indices[0],correction=readOptionCorrection(command,flag,invocationArgv[index],invocationArgv[index+1]);if(!correction)return;const{replacement,consumed,conflicts}=correction;if(!invocationArgv.some(argument=>conflicts.includes(argument.split("=",1)[0])))return[...invocationArgv.slice(0,index),...replacement,...invocationArgv.slice(index+consumed)]}function isReadProjectionRecoveryFlag(flag){const normalized=flag.split("=",1)[0].replaceAll("_","-");return READ_PROJECTION_FLAGS.has(normalized)||normalized.length>=5&&[...READ_PROJECTION_FLAGS].some(candidate=>candidate.startsWith(normalized))}function isCompatibleRecoveryFlag(requested,candidate){const unknownFlag=requested.split("=",1)[0].replaceAll("_","-");return isReadProjectionRecoveryFlag(unknownFlag)?!MUTATION_RECEIPT_FLAGS.has(candidate):MUTATION_RECEIPT_FLAGS.has(unknownFlag)?!isReadProjectionRecoveryFlag(candidate):!0}function normalizeMissingFlag(label){return label.trim().match(/--[a-z0-9][a-z0-9_-]*/i)?.[0]?.replaceAll("_","-").toLowerCase()}function resolveRecoveryCommandName(invocationArgv){if(!(!Array.isArray(invocationArgv)||invocationArgv.length===0))return parseBootstrapCommandName(invocationArgv)}function resolveMissingOptionPlaceholder(commandName,missingLabel){const flag=normalizeMissingFlag(missingLabel);if(!flag)return;const contract=resolveSubcommandFlagContractsForCommand(commandName).find(entry=>entry.flag===flag||entry.aliases?.includes(flag));return contract?contract.value_type==="boolean"?null:`<${contract.value_name??"value"}>`:"<value>"}function renderMissingOptionRetry(invocationArgv,commandName,missingLabels){const retry=[...invocationArgv],terminatorIndex=retry.indexOf("--");let insertionIndex=terminatorIndex<0?retry.length:terminatorIndex;for(const label of missingLabels){const flag=normalizeMissingFlag(label);if(!flag||retry.slice(0,insertionIndex).some(token=>token===flag||token.startsWith(`${flag}=`)))continue;const placeholder=resolveMissingOptionPlaceholder(commandName,flag),recoveredOption=placeholder?[flag,placeholder]:[flag];retry.splice(insertionIndex,0,...recoveredOption),insertionIndex+=recoveredOption.length}return retry.length===invocationArgv.length?void 0:renderPmCommand(retry)}export{describeReadCompletenessControls,isCompatibleRecoveryFlag,isReadProjectionRecoveryFlag,renderMissingOptionRetry,resolveLifecycleVerbRecovery,resolveLinkedResourcePositionalRecovery,resolveMissingOptionPlaceholder,resolveReadCompletenessControls,resolveReadOptionRetryArgs,resolveRecoveryCommandName};
|
|
2
2
|
//# sourceMappingURL=command-recovery.js.map
|