@unbrained/pm-cli 2026.10.17 → 2026.10.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +25 -0
  3. package/dist/cli/register-list-query.js +2 -2
  4. package/dist/cli-bundle/bundle-manifest.json +1 -1
  5. package/dist/cli-bundle/chunks/{chunk-3QKI3XNX.js → chunk-4GA4MUTE.js} +2 -2
  6. package/dist/cli-bundle/chunks/{chunk-X2ONXFBP.js → chunk-4V6ONLI6.js} +2 -2
  7. package/dist/cli-bundle/chunks/{chunk-B5QVGCZX.js → chunk-6VZKYJW7.js} +2 -2
  8. package/dist/cli-bundle/chunks/chunk-7PATQWTH.js +20 -0
  9. package/dist/cli-bundle/chunks/{chunk-W3KZ22DW.js → chunk-7WIEAGDS.js} +2 -2
  10. package/dist/cli-bundle/chunks/{chunk-EA2CG7UM.js → chunk-AETP4JEM.js} +2 -2
  11. package/dist/cli-bundle/chunks/{chunk-6ZDKKOKM.js → chunk-FIJOSX2C.js} +2 -2
  12. package/dist/cli-bundle/chunks/{chunk-VMCSTFSO.js → chunk-LUKVNL72.js} +2 -2
  13. package/dist/cli-bundle/chunks/{chunk-J4LPQCET.js → chunk-OJ77ZQN3.js} +2 -2
  14. package/dist/cli-bundle/chunks/{chunk-O4YBC3OM.js → chunk-PYRREEUB.js} +30 -30
  15. package/dist/cli-bundle/chunks/chunk-RHQJ6VWC.js +237 -0
  16. package/dist/cli-bundle/chunks/{chunk-OZCSXX4D.js → chunk-RNABUEFB.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-HY7FQ7QX.js → chunk-TO6CIV4C.js} +2 -2
  18. package/dist/cli-bundle/chunks/{chunk-JS3B2M4D.js → chunk-ZZED447K.js} +2 -2
  19. package/dist/cli-bundle/chunks/{register-list-query-RU3QZSAQ.js → register-list-query-PUCVYYBD.js} +7 -7
  20. package/dist/cli-bundle/chunks/{register-mutation-EQYMT32A.js → register-mutation-GGGVBXD5.js} +2 -2
  21. package/dist/cli-bundle/chunks/{register-operations-VXBGE4XI.js → register-operations-NRZ6Q4QE.js} +2 -2
  22. package/dist/cli-bundle/chunks/{register-setup-UUDEGFRO.js → register-setup-MV3P3YSF.js} +2 -2
  23. package/dist/cli-bundle/focused-chunks/{chunk-LDKX4KYJ.js → chunk-2MPQUMTF.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/{chunk-MBQF6HT6.js → chunk-5UKCSZWT.js} +2 -2
  25. package/dist/cli-bundle/focused-chunks/{chunk-FTUZ3JF2.js → chunk-A4ZHHTEX.js} +2 -2
  26. package/dist/cli-bundle/focused-chunks/{chunk-JXR6UKFM.js → chunk-B4YLP5ZB.js} +2 -2
  27. package/dist/cli-bundle/focused-chunks/{chunk-NZO7GOXD.js → chunk-BFEMT5U3.js} +16 -16
  28. package/dist/cli-bundle/focused-chunks/{chunk-QOSVJDOO.js → chunk-FW7CSSKL.js} +61 -61
  29. package/dist/cli-bundle/focused-chunks/{chunk-AH6NX6GM.js → chunk-HYPRPSYD.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-RBLSY6ML.js → chunk-IRVL4UXR.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/{chunk-RHTH5ILM.js → chunk-L55KQ2KT.js} +2 -2
  32. package/dist/cli-bundle/focused-chunks/{chunk-PYC7BF6Z.js → chunk-MASIOFPG.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-RJ3EIHDU.js +26 -0
  34. package/dist/cli-bundle/focused-chunks/chunk-SEL4Z2OO.js +167 -0
  35. package/dist/cli-bundle/focused-chunks/{chunk-2IOHHNRT.js → chunk-TB7F4FCR.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/{chunk-UNTQE37U.js → chunk-TZUIBG3P.js} +2 -2
  37. package/dist/cli-bundle/focused-chunks/{chunk-E33QA7PK.js → chunk-Z7YIFCNE.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/{chunk-SIGIGZCG.js → chunk-ZDBS2DCT.js} +2 -2
  39. package/dist/cli-bundle/main.js +2 -2
  40. package/dist/cli-bundle/sdk-authoring.js +1 -1
  41. package/dist/cli-bundle/sdk-contracts.js +1 -1
  42. package/dist/cli-bundle/sdk-core.js +16 -16
  43. package/dist/cli-bundle/sdk-governance.js +1 -1
  44. package/dist/cli-bundle/sdk-graph.js +1 -1
  45. package/dist/cli-bundle/sdk-merge.js +50 -49
  46. package/dist/cli-bundle/sdk-query.js +1 -1
  47. package/dist/cli-bundle/sdk-runtime.js +1 -1
  48. package/dist/cli-bundle/sdk-testing.js +1 -1
  49. package/dist/cli-bundle/sdk.js +1 -1
  50. package/dist/core/history/event-index.d.ts +8 -1
  51. package/dist/core/history/event-index.js +19 -18
  52. package/dist/core/item/item-format.js +1 -1
  53. package/dist/core/lock/lock.d.ts +8 -1
  54. package/dist/core/lock/lock.js +3 -3
  55. package/dist/core/output/output.js +2 -2
  56. package/dist/core/store/paths.js +1 -1
  57. package/dist/core/telemetry/policy.d.ts +2 -0
  58. package/dist/core/telemetry/policy.js +1 -1
  59. package/dist/core/telemetry/runtime.d.ts +5 -3
  60. package/dist/core/telemetry/runtime.js +3 -3
  61. package/dist/sdk/governance/health/projection.d.ts +37 -0
  62. package/dist/sdk/governance/health/projection.js +2 -0
  63. package/dist/sdk/governance/health.d.ts +7 -18
  64. package/dist/sdk/governance/health.js +2 -2
  65. package/dist/sdk/mutation-events.js +1 -1
  66. package/dist/sdk/public-surface.json +1 -1
  67. package/dist/sdk/query/list.d.ts +2 -0
  68. package/dist/sdk/query/list.js +1 -1
  69. package/dist/types.d.ts +2 -2
  70. package/dist/types.js +1 -1
  71. package/docs/COMMANDS.md +26 -0
  72. package/docs/CONFIGURATION.md +22 -1
  73. package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +22 -3
  74. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +10 -0
  75. package/docs/RELEASING.md +8 -1
  76. package/docs/SDK_CONTEXT_COORDINATION.md +71 -7
  77. package/docs/SDK_STORAGE_LIFECYCLE.md +24 -2
  78. package/docs/TESTING.md +8 -0
  79. package/docs/examples/ci/github-actions-pm-extension-gate.yml +1 -1
  80. package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +1 -1
  81. package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +1 -1
  82. package/marketplace.json +1 -1
  83. package/node_modules/@opentelemetry/core/package.json +2 -1
  84. package/node_modules/@opentelemetry/instrumentation/package.json +2 -1
  85. package/node_modules/@opentelemetry/resources/package.json +2 -1
  86. package/node_modules/@opentelemetry/sdk-trace/package.json +2 -1
  87. package/node_modules/@opentelemetry/sdk-trace-base/package.json +2 -1
  88. package/node_modules/@sentry/core/build/cjs/client.js +5 -4
  89. package/node_modules/@sentry/core/build/cjs/tracing/ai/gen-ai-attributes.js +0 -4
  90. package/node_modules/@sentry/core/build/cjs/tracing/ai/utils.js +33 -23
  91. package/node_modules/@sentry/core/build/cjs/tracing/anthropic-ai/index.js +7 -6
  92. package/node_modules/@sentry/core/build/cjs/tracing/anthropic-ai/streaming.js +3 -1
  93. package/node_modules/@sentry/core/build/cjs/tracing/google-genai/index.js +13 -14
  94. package/node_modules/@sentry/core/build/cjs/tracing/google-genai/streaming.js +6 -1
  95. package/node_modules/@sentry/core/build/cjs/tracing/langchain/utils.js +71 -21
  96. package/node_modules/@sentry/core/build/cjs/tracing/langgraph/utils.js +23 -33
  97. package/node_modules/@sentry/core/build/cjs/tracing/openai/streaming.js +6 -0
  98. package/node_modules/@sentry/core/build/cjs/tracing/openai/utils.js +11 -0
  99. package/node_modules/@sentry/core/build/cjs/tracing/workers-ai/utils.js +1 -1
  100. package/node_modules/@sentry/core/build/cjs/utils/eventUtils.js +4 -0
  101. package/node_modules/@sentry/core/build/cjs/utils/prepareEvent.js +2 -2
  102. package/node_modules/@sentry/core/build/cjs/utils/version.js +1 -1
  103. package/node_modules/@sentry/core/build/esm/client.js +6 -5
  104. package/node_modules/@sentry/core/build/esm/package.json +1 -1
  105. package/node_modules/@sentry/core/build/esm/tracing/ai/gen-ai-attributes.js +1 -3
  106. package/node_modules/@sentry/core/build/esm/tracing/ai/utils.js +34 -24
  107. package/node_modules/@sentry/core/build/esm/tracing/anthropic-ai/index.js +8 -7
  108. package/node_modules/@sentry/core/build/esm/tracing/anthropic-ai/streaming.js +3 -1
  109. package/node_modules/@sentry/core/build/esm/tracing/google-genai/index.js +15 -16
  110. package/node_modules/@sentry/core/build/esm/tracing/google-genai/streaming.js +6 -1
  111. package/node_modules/@sentry/core/build/esm/tracing/langchain/utils.js +73 -24
  112. package/node_modules/@sentry/core/build/esm/tracing/langgraph/utils.js +24 -34
  113. package/node_modules/@sentry/core/build/esm/tracing/openai/streaming.js +6 -0
  114. package/node_modules/@sentry/core/build/esm/tracing/openai/utils.js +11 -0
  115. package/node_modules/@sentry/core/build/esm/tracing/workers-ai/utils.js +2 -2
  116. package/node_modules/@sentry/core/build/esm/utils/eventUtils.js +4 -1
  117. package/node_modules/@sentry/core/build/esm/utils/prepareEvent.js +2 -2
  118. package/node_modules/@sentry/core/build/esm/utils/version.js +1 -1
  119. package/node_modules/@sentry/core/build/types/tracing/ai/utils.d.ts +3 -7
  120. package/node_modules/@sentry/core/build/types/tracing/anthropic-ai/types.d.ts +2 -2
  121. package/node_modules/@sentry/core/build/types/tracing/langchain/types.d.ts +15 -0
  122. package/node_modules/@sentry/core/build/types/tracing/langchain/utils.d.ts +1 -0
  123. package/node_modules/@sentry/core/build/types/tracing/langgraph/utils.d.ts +2 -0
  124. package/node_modules/@sentry/core/build/types/tracing/openai/types.d.ts +2 -0
  125. package/node_modules/@sentry/core/build/types/utils/eventUtils.d.ts +2 -1
  126. package/node_modules/@sentry/core/build/types-ts3.8/tracing/ai/utils.d.ts +3 -7
  127. package/node_modules/@sentry/core/build/types-ts3.8/tracing/anthropic-ai/types.d.ts +2 -2
  128. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langchain/types.d.ts +15 -0
  129. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langchain/utils.d.ts +1 -0
  130. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langgraph/utils.d.ts +2 -0
  131. package/node_modules/@sentry/core/build/types-ts3.8/tracing/openai/types.d.ts +2 -0
  132. package/node_modules/@sentry/core/build/types-ts3.8/utils/eventUtils.d.ts +2 -1
  133. package/node_modules/@sentry/core/package.json +1 -1
  134. package/node_modules/@sentry/node/build/esm/package.json +1 -1
  135. package/node_modules/@sentry/node/package.json +5 -5
  136. package/node_modules/@sentry/node-core/build/cjs/integrations/anr/index.js +1 -1
  137. package/node_modules/@sentry/node-core/build/cjs/integrations/local-variables/local-variables-async.js +1 -1
  138. package/node_modules/@sentry/node-core/build/esm/integrations/anr/index.js +1 -1
  139. package/node_modules/@sentry/node-core/build/esm/integrations/anr/worker-script.js +2 -2
  140. package/node_modules/@sentry/node-core/build/esm/integrations/local-variables/local-variables-async.js +1 -1
  141. package/node_modules/@sentry/node-core/build/esm/integrations/local-variables/worker-script.js +1 -1
  142. package/node_modules/@sentry/node-core/build/esm/package.json +1 -1
  143. package/node_modules/@sentry/node-core/package.json +10 -4
  144. package/node_modules/@sentry/opentelemetry/build/esm/package.json +1 -1
  145. package/node_modules/@sentry/opentelemetry/package.json +5 -2
  146. package/node_modules/@sentry/server-utils/build/THIRD-PARTY-LICENSES.txt +55 -55
  147. package/node_modules/@sentry/server-utils/build/esm/package.json +1 -1
  148. package/node_modules/@sentry/server-utils/package.json +2 -2
  149. package/node_modules/@toon-format/toon/README.md +10 -41
  150. package/node_modules/@toon-format/toon/dist/index.d.mts +12 -36
  151. package/node_modules/@toon-format/toon/dist/index.mjs +134 -202
  152. package/node_modules/@toon-format/toon/package.json +2 -2
  153. package/node_modules/debug/package.json +3 -0
  154. package/node_modules/fdir/package.json +3 -0
  155. package/node_modules/has-flag/index.d.ts +39 -0
  156. package/node_modules/has-flag/index.js +8 -0
  157. package/node_modules/has-flag/license +9 -0
  158. package/node_modules/has-flag/package.json +46 -0
  159. package/node_modules/has-flag/readme.md +89 -0
  160. package/node_modules/supports-color/browser.js +5 -0
  161. package/node_modules/supports-color/index.js +135 -0
  162. package/node_modules/supports-color/license +9 -0
  163. package/node_modules/supports-color/package.json +53 -0
  164. package/node_modules/supports-color/readme.md +76 -0
  165. package/package.json +4 -4
  166. package/packages/pm-beads/package.json +1 -1
  167. package/packages/pm-calendar/package.json +1 -1
  168. package/packages/pm-command-kit/package.json +1 -1
  169. package/packages/pm-digital-twin/package.json +1 -1
  170. package/packages/pm-governance-audit/package.json +1 -1
  171. package/packages/pm-guide-shell/package.json +1 -1
  172. package/packages/pm-kanban/package.json +1 -1
  173. package/packages/pm-lifecycle-hooks/package.json +1 -1
  174. package/packages/pm-linked-test-adapters/package.json +1 -1
  175. package/packages/pm-search-advanced/package.json +1 -1
  176. package/packages/pm-templates/package.json +1 -1
  177. package/packages/pm-todos/package.json +1 -1
  178. package/packages/pm-vcs/package.json +1 -1
  179. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  180. package/plugins/pm-claude/package.json +1 -1
  181. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  182. package/plugins/pm-codex/package.json +1 -1
  183. package/plugins/pm-codex/plugin.json +1 -1
  184. package/runtime-dependencies.json +1 -1
  185. package/dist/cli-bundle/chunks/chunk-4PNPDT2N.js +0 -236
  186. package/dist/cli-bundle/chunks/chunk-X53HM753.js +0 -20
  187. package/dist/cli-bundle/focused-chunks/chunk-5JEFDEL3.js +0 -166
  188. package/dist/cli-bundle/focused-chunks/chunk-TRFVAWF2.js +0 -26
@@ -1,10 +1,10 @@
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]="11e932b0-f880-5848-abd3-0360e21289ec")}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,resolveTelemetryEnvironmentPolicy}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_SOURCE_CONTEXT_ENV="PM_TELEMETRY_SOURCE_CONTEXT",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 PM_TELEMETRY_SOURCE_CONTEXT_SET=new Set(PM_TELEMETRY_SOURCE_CONTEXT_VALUES),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(){if(parseBooleanTrueLike(process.env[PM_TELEMETRY_INLINE_FLUSH_ENV])||parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV]))return!0;const nodeEnv=(process.env.NODE_ENV??"").trim().toLowerCase();return typeof process.env.VITEST=="string"||typeof process.env.VITEST_WORKER_ID=="string"||nodeEnv==="test"}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)}
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]="1496ef0f-a192-5491-b84b-ea7da6cce65e")}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}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_SOURCE_CONTEXT_ENV="PM_TELEMETRY_SOURCE_CONTEXT",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 PM_TELEMETRY_SOURCE_CONTEXT_SET=new Set(PM_TELEMETRY_SOURCE_CONTEXT_VALUES),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
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"&&params.errorCategory.trim().length>0?params.errorCategory:typeof params.errorCode=="string"&&params.errorCode.trim().length>0?resolveTelemetryErrorCategory(params.errorCode):"unknown"}function resolveTelemetrySourceContext(globalOptions){const override=(process.env[PM_TELEMETRY_SOURCE_CONTEXT_ENV]??"").trim().toLowerCase();if(PM_TELEMETRY_SOURCE_CONTEXT_SET.has(override))return{source_context:override,source_context_source:"env_override"};const source=override.length>0?"env_override_rejected":"inferred";return 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
- `)),{source_context:inferTelemetrySourceContext(globalOptions),source_context_source:source}}function inferTelemetrySourceContext(globalOptions){const nodeEnv=(process.env.NODE_ENV??"").trim().toLowerCase();if(typeof process.env.VITEST=="string"||typeof process.env.VITEST_WORKER_ID=="string"||nodeEnv==="test")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(`
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(`
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(`
7
7
  `)){const trimmed=line.trim();if(trimmed.length!==0)try{const parsed=JSON.parse(trimmed);parsed&&typeof parsed=="object"&&typeof parsed.endpoint=="string"&&parsed.endpoint.trim().length>0&&"payload"in parsed&&typeof parsed.attempts=="number"&&Number.isFinite(parsed.attempts)&&((typeof parsed.id!="string"||parsed.id.length===0)&&(parsed.id=backfillPendingOtelSpanId(parsed)),entries.push(parsed))}catch{}}return entries}function isExpiredPendingOtelSpan(entry,cutoffMs){if(typeof entry.enqueued_at!="string"||entry.enqueued_at.trim().length===0)return!1;const enqueuedAtMs=Date.parse(entry.enqueued_at);return Number.isNaN(enqueuedAtMs)?!1:enqueuedAtMs<cutoffMs}function prunePendingOtelSpans(entries,retentionDays){const cutoffMs=retentionCutoffMs(retentionDays),retained=[];let prunedCount=0;for(const entry of entries){if(JSON.stringify(entry).length>TELEMETRY_MAX_EVENT_BYTES||isExpiredPendingOtelSpan(entry,cutoffMs)||entry.attempts>=TELEMETRY_MAX_QUEUE_ENTRY_ATTEMPTS){prunedCount+=1;continue}retained.push(entry)}if(retained.length>TELEMETRY_OTEL_SPANS_MAX_PENDING){const overflow=retained.length-TELEMETRY_OTEL_SPANS_MAX_PENDING;return prunedCount+=overflow,{entries:retained.slice(overflow),prunedCount}}return{entries:retained,prunedCount}}async function rewritePendingOtelSpans(globalPmRoot,entries){const serialized=entries.map(entry=>JSON.stringify(entry)).join(`
8
8
  `),contents=serialized.length>0?`${serialized}
9
- `:"";for(let attempt=0;;attempt+=1)try{await writeFileAtomic(otelSpansQueuePath(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)}}async function reconcilePendingOtelSpansAfterFlush(globalPmRoot,retentionDays,succeededIds,failedUpdates){return withQueueMutation(async()=>{const raw=await readFileIfExists(otelSpansQueuePath(globalPmRoot)),current=raw===null?[]:parsePendingOtelSpanLines(raw),reconciled=[];for(const entry of current){if(succeededIds.has(entry.id))continue;const failure=failedUpdates.get(entry.id);reconciled.push(failure?{...entry,attempts:failure.attempts,next_attempt_after:failure.next_attempt_after}:entry)}const{entries:retained}=prunePendingOtelSpans(reconciled,retentionDays);return await rewritePendingOtelSpans(globalPmRoot,retained),retained.length},globalPmRoot)}async function flushPendingOtelSpans(globalPmRoot,retentionDays){const raw=await readFileIfExists(otelSpansQueuePath(globalPmRoot));if(raw===null||raw.trim().length===0){await writeRuntimeState(globalPmRoot,{pending_otel_spans:0});return}const entries=parsePendingOtelSpanLines(raw),{entries:retained,prunedCount}=prunePendingOtelSpans(entries,retentionDays),due=retained.filter(entry=>isDueForRetryAt(entry.next_attempt_after)).slice(0,TELEMETRY_OTEL_SPANS_FLUSH_BATCH_SIZE);if(due.length===0){const remaining2=prunedCount>0?await reconcilePendingOtelSpansAfterFlush(globalPmRoot,retentionDays,new Set,new Map):retained.length;await writeRuntimeState(globalPmRoot,{pending_otel_spans:remaining2});return}const attemptTime=nowIso(),succeededIds=new Set,failedUpdates=new Map;let succeededCount=0,lastError;await Promise.all(due.map(async span=>{try{const status=await postTelemetryJson(span.endpoint,{"content-type":"application/json"},JSON.stringify(span.payload));if(status<200||status>=300)throw new Error(`local_otel_export_http_${status}`);succeededIds.add(span.id),succeededCount+=1}catch(error){lastError=error instanceof Error?sanitizeString(error.message,"redacted"):"local_otel_export_failed";const nextAttempts=span.attempts+1;failedUpdates.set(span.id,{attempts:nextAttempts,next_attempt_after:nextRetryIso(nextAttempts)})}}));const remaining=await reconcilePendingOtelSpansAfterFlush(globalPmRoot,retentionDays,succeededIds,failedUpdates),statePatch={pending_otel_spans:remaining,last_otel_attempt_at:attemptTime};succeededCount>0&&(statePatch.last_otel_success_at=attemptTime),lastError!==void 0?(statePatch.last_otel_failure_at=attemptTime,statePatch.last_otel_failure_error=lastError):remaining===0&&(statePatch.last_otel_failure_at=void 0,statePatch.last_otel_failure_error=void 0),await writeRuntimeState(globalPmRoot,statePatch)}async function flushTelemetryArtifacts(globalPmRoot,endpoint,retentionDays){try{await flushQueue(globalPmRoot,endpoint,retentionDays)}catch{}try{await flushPendingOtelSpans(globalPmRoot,retentionDays)}catch{}}async function cleanupTelemetryQueueTempOrphans(globalPmRoot,maxAgeMs=TELEMETRY_QUEUE_TMP_ORPHAN_MAX_AGE_MS){try{const dirPath=telemetryRuntimeDirectory(globalPmRoot),entries=await readdir(dirPath,{withFileTypes:!0}),cutoffMs=Date.now()-Math.max(0,maxAgeMs);await Promise.all(entries.filter(entry=>entry.isFile()&&/^\.events\.jsonl\.\d+\.\d+\.[a-f0-9]+\.tmp$/.test(entry.name)).map(async entry=>{const candidate=path.join(dirPath,entry.name);(await stat(candidate)).mtimeMs<cutoffMs&&await rm(candidate,{force:!0})}))}catch{}}async function withQueueMutation(operation,globalPmRoot=resolveGlobalPmRoot(process.cwd()),waitMs=5e3){const run=_queueMutationPromise.catch(()=>{}).then(()=>runWithIsolatedExtensionRuntime(async()=>{const release=await acquireLock(globalPmRoot,"telemetry-queue",60,"telemetry",!1,!1,waitMs,{createParentDirectories:!parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV])});try{return clearSettingsReadCache(globalPmRoot),await operation()}finally{await release()}}));return _queueMutationPromise=run.catch(()=>{}),run}async function readCurrentQueueEntries(globalPmRoot){const raw=await readFileIfExists(queuePath(globalPmRoot));return raw===null||raw.trim().length===0?[]:parseQueueLines(raw)}async function removeFlushedEntriesFromCurrentQueue(globalPmRoot,flushedIds,retentionDays){return withQueueMutation(async()=>{const currentEntries=await readCurrentQueueEntries(globalPmRoot),{entries:retainedEntries}=pruneExpiredQueueEntries(currentEntries,retentionDays),remaining=retainedEntries.filter(entry=>!flushedIds.has(entry.event.event_id));return await rewriteQueue(globalPmRoot,remaining),remaining},globalPmRoot)}async function markFailedEntriesInCurrentQueue(globalPmRoot,failedIds,attemptTime,retentionDays){return withQueueMutation(async()=>{const currentEntries=await readCurrentQueueEntries(globalPmRoot),{entries:retainedEntries}=pruneExpiredQueueEntries(currentEntries,retentionDays),retried=retainedEntries.map(entry=>{if(!failedIds.has(entry.event.event_id))return entry;const attempts=entry.attempts+1;return{...entry,attempts,last_attempt_at:attemptTime,next_attempt_after:nextRetryIso(attempts)}});return await rewriteQueue(globalPmRoot,retried),retried},globalPmRoot)}async function flushQueue(globalPmRoot,endpoint,retentionDays){await cleanupTelemetryQueueTempOrphans(globalPmRoot);const normalizedEndpoint=endpoint.trim();if(normalizedEndpoint.length===0)return;const raw=await readFileIfExists(queuePath(globalPmRoot));if(raw===null||raw.trim().length===0){await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:0});return}const queueEntries=parseQueueLines(raw);if(queueEntries.length===0){await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:0});return}const{entries:retainedEntries,prunedCount}=pruneExpiredQueueEntries(queueEntries,retentionDays);if(retainedEntries.length===0){const remaining=await removeFlushedEntriesFromCurrentQueue(globalPmRoot,new Set,retentionDays);await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:remaining.length});return}const dueEntries=retainedEntries.filter(entry=>isDueForRetry(entry)).slice(0,TELEMETRY_FLUSH_BATCH_SIZE);if(dueEntries.length===0){const remaining=prunedCount>0?await removeFlushedEntriesFromCurrentQueue(globalPmRoot,new Set,retentionDays):retainedEntries;await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:remaining.length});return}const dueIds=new Set(dueEntries.map(entry=>entry.event.event_id)),attemptTime=nowIso(),requestHeaders={"content-type":"application/json"},ingestKey=process.env.PM_TELEMETRY_INGEST_KEY?.trim();ingestKey&&(requestHeaders["x-pm-telemetry-key"]=ingestKey);try{const status=await postTelemetryJson(normalizedEndpoint,requestHeaders,JSON.stringify({schema_version:TELEMETRY_SCHEMA_VERSION,events:dueEntries.map(entry=>entry.event)}));if(status<200||status>=300)throw new Error(`telemetry_flush_http_${status}`)}catch(error){const retried=await markFailedEntriesInCurrentQueue(globalPmRoot,dueIds,attemptTime,retentionDays),errorMessage=error instanceof Error?sanitizeString(error.message,"redacted"):"telemetry_flush_failed";await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:retried.length,last_attempted_flush_at:attemptTime,last_failed_flush_at:attemptTime,last_failed_flush_error:errorMessage});return}try{const remaining=await removeFlushedEntriesFromCurrentQueue(globalPmRoot,dueIds,retentionDays);await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:remaining.length,last_attempted_flush_at:attemptTime,last_successful_flush_at:attemptTime,last_failed_flush_at:void 0,last_failed_flush_error:void 0})}catch(error){const errorMessage=error instanceof Error?sanitizeString(error.message,"redacted"):"telemetry_flush_failed",currentEntries=await readCurrentQueueEntries(globalPmRoot).catch(()=>retainedEntries);await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:currentEntries.length,last_attempted_flush_at:attemptTime,last_failed_flush_at:attemptTime,last_failed_flush_error:errorMessage})}}async function acquireTelemetryFlushLock(globalPmRoot){const lockPath=flushLockPath(globalPmRoot);parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV])||await mkdir(path.dirname(lockPath),{recursive:!0});try{return await mkdir(lockPath),!0}catch(error){if(typeof error!="object"||error===null||!("code"in error)||error.code!=="EEXIST")throw error}try{const lockStats=await stat(lockPath);return Date.now()-lockStats.mtimeMs<TELEMETRY_FLUSH_LOCK_STALE_MS?!1:(await rm(lockPath,{recursive:!0,force:!0}),await mkdir(lockPath),!0)}catch{return!1}}function isFreshDirectoryLock(lockPath,staleMs){try{return Date.now()-statSync(lockPath).mtimeMs<staleMs}catch{return!1}}function removeDirectoryLockBestEffort(lockPath){try{rmSync(lockPath,{recursive:!0,force:!0})}catch{}}function errorCode(error){if(typeof error!="object"||error===null||!("code"in error))return;const code=error.code;return typeof code=="string"?code:void 0}function createDirectoryLock(lockPath){try{return mkdirSync(lockPath),!0}catch(error){if(errorCode(error)==="EEXIST"||!isFileMissingError(error))return!1}try{return mkdirSync(path.dirname(lockPath),{recursive:!0}),mkdirSync(lockPath),!0}catch{return!1}}function acquireTelemetryFlushSpawnGate(globalPmRoot){if(isFreshDirectoryLock(flushLockPath(globalPmRoot),TELEMETRY_FLUSH_LOCK_STALE_MS))return!1;const lockPath=flushSpawnLockPath(globalPmRoot);try{if(Date.now()-statSync(lockPath).mtimeMs<TELEMETRY_FLUSH_SPAWN_LOCK_STALE_MS)return!1;removeDirectoryLockBestEffort(lockPath)}catch(error){if(!isFileMissingError(error))return!1}return createDirectoryLock(lockPath)}function releaseTelemetryFlushSpawnGate(globalPmRoot){removeDirectoryLockBestEffort(flushSpawnLockPath(globalPmRoot))}const _testOnly={acquireTelemetryFlushSpawnGate,acquireTelemetryFlushLock,buildAuthorContextPayloadFields,buildCommandErrorPayload,buildCommandFinishPayload,buildCommandStartPayload,buildOtelSpanRequest,createDirectoryLock,enqueuePendingOtelSpan,enqueueTelemetryEvent,errorCode,flushPendingOtelSpans,flushQueue,flushQueueWithProcessLock,flushTelemetryArtifacts,hashTelemetryErrorFingerprint,hashTelemetryValue,isEmailDomainCharacter,isEmailLocalCharacter,isExpiredPendingOtelSpan,isExpiredQueueEntry,isFreshDirectoryLock,isDueForRetry,isDueForRetryAt,isRetryableQueueRewriteError,looksLikeEmailToken,otelSpansQueuePath,parseBooleanTrueLike,postTelemetryJson,parsePendingOtelSpanLines,prunePendingOtelSpans,reconcilePendingOtelSpansAfterFlush,retentionCutoffMs,resolveOtelTracesEndpoint,resolveTelemetryHttpTimeoutMs,rewritePendingOtelSpans,normalizeForHash,normalizeCaptureLevel,normalizePmVersion,normalizeTelemetryErrorCategory,normalizeTelemetryErrorCode,normalizeTelemetryExitCode,parseQueueLines,pruneExpiredQueueEntries,readRuntimeState,readCurrentQueueEntries,releaseTelemetryFlushSpawnGate,removeFlushedEntriesFromCurrentQueue,removeDirectoryLockBestEffort,resolveTelemetrySourceContext,rewriteQueue,sanitizeCommandArgs,sanitizeStringMax,sanitizeStringRedacted,sanitizeValue,scheduleTelemetryFlush,shouldFlushInline,sleep,summarizeResult,telemetryFlushRunnerPath,withQueueMutation,flushLockPath,flushSpawnLockPath,runtimeStatePath,writeRuntimeState};async function flushQueueWithProcessLock(globalPmRoot,endpoint,retentionDays){const acquired=await acquireTelemetryFlushLock(globalPmRoot);if(releaseTelemetryFlushSpawnGate(globalPmRoot),!acquired)return!1;try{await flushTelemetryArtifacts(globalPmRoot,endpoint,retentionDays)}finally{try{await rm(flushLockPath(globalPmRoot),{recursive:!0,force:!0})}catch{}}return!0}async function dueTelemetryArtifactIds(globalPmRoot,retentionDays){const ids=new Set;try{const{entries}=pruneExpiredQueueEntries(await readCurrentQueueEntries(globalPmRoot),retentionDays);for(const entry of entries.filter(isDueForRetry))ids.add(`event:${entry.event.event_id}`)}catch{}try{const raw=await readFileIfExists(otelSpansQueuePath(globalPmRoot));if(raw!==null)for(const entry of prunePendingOtelSpans(parsePendingOtelSpanLines(raw),retentionDays).entries)isDueForRetryAt(entry.next_attempt_after)&&ids.add(`span:${entry.id}`)}catch{}return ids}function scheduleTelemetryFlush(globalPmRoot,endpoint,retentionDays){if(!isConfigurationOnlySettingsRead(globalPmRoot)){if(shouldFlushInline()){const previousFlush=_lastFlushPromise,nextFlush=flushTelemetryArtifacts(globalPmRoot,endpoint,retentionDays);_lastFlushPromise=Promise.allSettled([previousFlush,nextFlush]).then(()=>{});return}try{if(!acquireTelemetryFlushSpawnGate(globalPmRoot))return;const child=spawn(process.execPath,[telemetryFlushRunnerPath()],{detached:!0,stdio:"ignore",cwd:os.tmpdir(),env:{...process.env,PM_GLOBAL_PATH:globalPmRoot,[PM_TELEMETRY_FLUSH_CHILD_ENV]:"1"}});child.on("error",()=>{releaseTelemetryFlushSpawnGate(globalPmRoot)}),child.unref()}catch{releaseTelemetryFlushSpawnGate(globalPmRoot)}}}async function flushTelemetryQueueNow(globalPmRoot=resolveGlobalPmRoot(process.cwd())){if(!resolveTelemetryEnvironmentPolicy().telemetry_disabled)try{await runWithConfigurationOnlySettings(globalPmRoot,async()=>{const detached=parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV]);let continueDraining=!0;for(;continueDraining;){if(!(await readSettings(globalPmRoot)).telemetry.enabled)return;const installation=await withQueueMutation(()=>ensureInstallationId(globalPmRoot),globalPmRoot);if(!installation)return;const before=detached?await dueTelemetryArtifactIds(globalPmRoot,installation.retentionDays):new Set;if(!await flushQueueWithProcessLock(globalPmRoot,installation.endpoint,installation.retentionDays)||!detached)return;const after=await dueTelemetryArtifactIds(globalPmRoot,installation.retentionDays);continueDraining=after.size>0&&(after.size!==before.size||[...after].some(id=>!before.has(id)))}},()=>parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV]))}catch{}}async function startTelemetryCommand(context){if(resolveTelemetryEnvironmentPolicy().telemetry_disabled||context.command==="telemetry"&&context.args.some(token=>token.trim().toLowerCase()==="clear"))return null;try{const globalPmRoot=resolveGlobalPmRoot(process.cwd());if(!(await readSettings(globalPmRoot)).telemetry.enabled)return null;const coreReadOwned=context.global.noExtensions===!0||isActiveCommandUnextended(context.command),activeCommand=await withQueueMutation(async()=>{const installation=await ensureInstallationId(globalPmRoot);if(!installation)return null;const{installationId,endpoint,retentionDays,captureLevel}=installation,pmVersion=normalizePmVersion(context.pm_version),sourceContext=resolveTelemetrySourceContext(context.global),pmRootHash=hashWithInstallationId(installationId,context.pm_root),cwdHash=hashWithInstallationId(installationId,process.cwd()),otelTracesEndpoint=resolveOtelTracesEndpoint(),occurredAt=nowIso(),event={schema_version:TELEMETRY_SCHEMA_VERSION,event_id:crypto.randomUUID(),event_type:"command_start",occurred_at:occurredAt,installation_id:installationId,session_id:PROCESS_SESSION_ID,command:context.command,payload:buildCommandStartPayload({captureLevel,context,pmVersion,sourceContext,pmRootHash,cwdHash,installationId})},sampleRate=await resolveAutomaticReadSampleRate(globalPmRoot,context.command,coreReadOwned);sampleRate===1&&await appendTelemetryEvent(globalPmRoot,event);const commandTaxonomy=deriveTelemetryCommandTaxonomy(context.command),active={...sampleRate<1?{sample_rate:sampleRate}:{},started_at:occurredAt,started_at_ms:Date.now(),command:context.command,command_taxonomy:commandTaxonomy,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,installation_id:installationId,pm_root_hash:pmRootHash,cwd_hash:cwdHash,endpoint,retention_days:retentionDays,global_pm_root:globalPmRoot,capture_level:captureLevel,otel_traces_endpoint:otelTracesEndpoint??void 0,otel_trace_id:otelTracesEndpoint?crypto.randomBytes(16).toString("hex"):void 0,otel_span_id:otelTracesEndpoint?crypto.randomBytes(8).toString("hex"):void 0};return sampleRate<1&&deferredReadStarts.set(active,event),active},globalPmRoot,TELEMETRY_FOREGROUND_LOCK_WAIT_MS);return activeCommand&&activeCommand.sample_rate===void 0&&scheduleTelemetryFlush(globalPmRoot,activeCommand.endpoint,activeCommand.retention_days),activeCommand}catch{return null}}async function finishTelemetryCommand(activeCommand,outcome){if(!(!activeCommand||resolveTelemetryEnvironmentPolicy().telemetry_disabled))try{if(!await withQueueMutation(async()=>{const settings=await readSettings(activeCommand.global_pm_root);if(resolveTelemetryEnvironmentPolicy().telemetry_disabled||!settings.telemetry.enabled||settings.telemetry.installation_id!==activeCommand.installation_id)return deferredReadStarts.delete(activeCommand),!1;const deferredStart=deferredReadStarts.get(activeCommand),sampleRate=outcome.ok?activeCommand.sample_rate??1:1;if(deferredStart){if(deferredReadStarts.delete(activeCommand),crypto.randomBytes(6).readUIntBE(0,6)/281474976710656>=sampleRate)return!1;deferredStart.payload.sample_rate=sampleRate,await appendTelemetryEvent(activeCommand.global_pm_root,deferredStart)}const finishedAt=nowIso(),durationMs=Math.max(0,Date.now()-activeCommand.started_at_ms),normalizedErrorCode=normalizeTelemetryErrorCode(inferTelemetryErrorCode({ok:outcome.ok,errorCode:outcome.error_code,errorMessage:outcome.error,exitCode:outcome.exit_code})),normalizedErrorCategory=normalizeTelemetryErrorCategory({ok:outcome.ok,errorCode:normalizedErrorCode,errorCategory:outcome.error_category}),normalizedExitCode=normalizeTelemetryExitCode(outcome.exit_code,outcome.ok),commandResolution=outcome.command_resolution??deriveTelemetryCommandResolution({ok:outcome.ok,errorCode:normalizedErrorCode,errorCategory:normalizedErrorCategory}),resolutionStage=outcome.resolution_stage??"execute",event={schema_version:TELEMETRY_SCHEMA_VERSION,event_id:crypto.randomUUID(),event_type:"command_finish",occurred_at:finishedAt,installation_id:activeCommand.installation_id,session_id:PROCESS_SESSION_ID,command:activeCommand.command,payload:{...deferredStart?{sample_rate:sampleRate}:{},...buildCommandFinishPayload({captureLevel:activeCommand.capture_level,pmVersion:activeCommand.pm_version,sourceContext:{source_context:activeCommand.source_context,source_context_source:activeCommand.source_context_source},outcome,durationMs,startedAt:activeCommand.started_at,command:activeCommand.command,installationId:activeCommand.installation_id,commandTaxonomy:activeCommand.command_taxonomy,exitCode:normalizedExitCode,errorCode:normalizedErrorCode,errorCategory:normalizedErrorCategory,commandResolution,resolutionStage})}};await appendTelemetryEvent(activeCommand.global_pm_root,event);const otelRequest=buildOtelSpanRequest(activeCommand,{...outcome,exit_code:normalizedExitCode,error_code:normalizedErrorCode,error_category:normalizedErrorCategory},finishedAt,durationMs,sampleRate);return otelRequest&&await appendPendingOtelSpan(activeCommand.global_pm_root,otelRequest),!0},activeCommand.global_pm_root,TELEMETRY_FOREGROUND_LOCK_WAIT_MS))return;scheduleTelemetryFlush(activeCommand.global_pm_root,activeCommand.endpoint,activeCommand.retention_days)}catch{}}async function emitTelemetryErrorEvent(context){if(!resolveTelemetryEnvironmentPolicy().telemetry_disabled)try{const globalPmRoot=resolveGlobalPmRoot(process.cwd());if(!(await readSettings(globalPmRoot)).telemetry.enabled)return;const captured=await withQueueMutation(async()=>{const installation=await ensureInstallationId(globalPmRoot);if(!installation)return null;const{installationId,captureLevel}=installation,pmVersion=normalizePmVersion(context.pm_version),sourceContext=resolveTelemetrySourceContext(context.global),pmRootHash=hashWithInstallationId(installationId,context.pm_root),cwdHash=hashWithInstallationId(installationId,process.cwd()),occurredAt=nowIso(),normalizedErrorCode=normalizeTelemetryErrorCode(inferTelemetryErrorCode({ok:!1,errorCode:context.error_code,errorMessage:context.error_message,exitCode:context.exit_code})),normalizedErrorCategory=context.error_category??resolveTelemetryErrorCategory(normalizedErrorCode),normalizedExitCode=normalizeTelemetryExitCode(context.exit_code,!1),normalizedCommand=context.command.trim().length>0?context.command:"<unknown>",commandTaxonomy=deriveTelemetryCommandTaxonomy(normalizedCommand),commandResolution=context.command_resolution??deriveTelemetryCommandResolution({ok:!1,errorCode:normalizedErrorCode,errorCategory:normalizedErrorCategory}),resolutionStage=context.resolution_stage??"unknown",event={schema_version:TELEMETRY_SCHEMA_VERSION,event_id:crypto.randomUUID(),event_type:"command_error",occurred_at:occurredAt,installation_id:installationId,session_id:PROCESS_SESSION_ID,command:sanitizeString(normalizedCommand,"redacted"),payload:buildCommandErrorPayload({captureLevel,pmVersion,sourceContext,command:normalizedCommand,commandTaxonomy,commandResolution,resolutionStage,args:context.args,options:context.options,pmRootHash,cwdHash,installationId,errorCode:normalizedErrorCode,errorCategory:normalizedErrorCategory,exitCode:normalizedExitCode,errorMessage:context.error_message})};return await appendTelemetryEvent(globalPmRoot,event),installation},globalPmRoot,TELEMETRY_FOREGROUND_LOCK_WAIT_MS);captured&&scheduleTelemetryFlush(globalPmRoot,captured.endpoint,captured.retentionDays)}catch{}}export{PM_TELEMETRY_SOURCE_CONTEXT_VALUES2 as PM_TELEMETRY_SOURCE_CONTEXT_VALUES,TELEMETRY_MAX_QUEUE_ENTRY_ATTEMPTS,TELEMETRY_SCHEMA_VERSION,_testOnly,emitTelemetryErrorEvent,finishTelemetryCommand,flushTelemetryQueueNow,startTelemetryCommand,waitForPendingFlush,withQueueMutation as withTelemetryQueueMutation};
9
+ `:"";for(let attempt=0;;attempt+=1)try{await writeFileAtomic(otelSpansQueuePath(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)}}async function reconcilePendingOtelSpansAfterFlush(globalPmRoot,retentionDays,succeededIds,failedUpdates){return withQueueMutation(async()=>{const raw=await readFileIfExists(otelSpansQueuePath(globalPmRoot)),current=raw===null?[]:parsePendingOtelSpanLines(raw),reconciled=[];for(const entry of current){if(succeededIds.has(entry.id))continue;const failure=failedUpdates.get(entry.id);reconciled.push(failure?{...entry,attempts:failure.attempts,next_attempt_after:failure.next_attempt_after}:entry)}const{entries:retained}=prunePendingOtelSpans(reconciled,retentionDays);return await rewritePendingOtelSpans(globalPmRoot,retained),retained.length},globalPmRoot)}async function flushPendingOtelSpans(globalPmRoot,retentionDays){const raw=await readFileIfExists(otelSpansQueuePath(globalPmRoot));if(raw===null||raw.trim().length===0){await writeRuntimeState(globalPmRoot,{pending_otel_spans:0});return}const entries=parsePendingOtelSpanLines(raw),{entries:retained,prunedCount}=prunePendingOtelSpans(entries,retentionDays),due=retained.filter(entry=>isDueForRetryAt(entry.next_attempt_after)).slice(0,TELEMETRY_OTEL_SPANS_FLUSH_BATCH_SIZE);if(due.length===0){const remaining2=prunedCount>0?await reconcilePendingOtelSpansAfterFlush(globalPmRoot,retentionDays,new Set,new Map):retained.length;await writeRuntimeState(globalPmRoot,{pending_otel_spans:remaining2});return}const attemptTime=nowIso(),succeededIds=new Set,failedUpdates=new Map;let succeededCount=0,lastError;await Promise.all(due.map(async span=>{try{const status=await postTelemetryJson(span.endpoint,{"content-type":"application/json"},JSON.stringify(span.payload));if(status<200||status>=300)throw new Error(`local_otel_export_http_${status}`);succeededIds.add(span.id),succeededCount+=1}catch(error){lastError=error instanceof Error?sanitizeString(error.message,"redacted"):"local_otel_export_failed";const nextAttempts=span.attempts+1;failedUpdates.set(span.id,{attempts:nextAttempts,next_attempt_after:nextRetryIso(nextAttempts)})}}));const remaining=await reconcilePendingOtelSpansAfterFlush(globalPmRoot,retentionDays,succeededIds,failedUpdates),statePatch={pending_otel_spans:remaining,last_otel_attempt_at:attemptTime};succeededCount>0&&(statePatch.last_otel_success_at=attemptTime),lastError!==void 0?(statePatch.last_otel_failure_at=attemptTime,statePatch.last_otel_failure_error=lastError):remaining===0&&(statePatch.last_otel_failure_at=void 0,statePatch.last_otel_failure_error=void 0),await writeRuntimeState(globalPmRoot,statePatch)}async function flushTelemetryArtifacts(globalPmRoot,endpoint,retentionDays){try{await flushQueue(globalPmRoot,endpoint,retentionDays)}catch{}try{await flushPendingOtelSpans(globalPmRoot,retentionDays)}catch{}}async function cleanupTelemetryQueueTempOrphans(globalPmRoot,maxAgeMs=TELEMETRY_QUEUE_TMP_ORPHAN_MAX_AGE_MS){try{const dirPath=telemetryRuntimeDirectory(globalPmRoot),entries=await readdir(dirPath,{withFileTypes:!0}),cutoffMs=Date.now()-Math.max(0,maxAgeMs);await Promise.all(entries.filter(entry=>entry.isFile()&&/^\.events\.jsonl\.\d+\.\d+\.[a-f0-9]+\.tmp$/.test(entry.name)).map(async entry=>{const candidate=path.join(dirPath,entry.name);(await stat(candidate)).mtimeMs<cutoffMs&&await rm(candidate,{force:!0})}))}catch{}}async function withQueueMutation(operation,globalPmRoot=resolveGlobalPmRoot(process.cwd()),waitMs=5e3){const run=_queueMutationPromise.catch(()=>{}).then(()=>runWithIsolatedExtensionRuntime(async()=>{const release=await acquireLock(globalPmRoot,"telemetry-queue",60,"telemetry",!1,!1,waitMs,{createParentDirectories:!parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV])});try{return clearSettingsReadCache(globalPmRoot),await operation()}finally{await release()}}));return _queueMutationPromise=run.catch(()=>{}),run}async function readCurrentQueueEntries(globalPmRoot){const raw=await readFileIfExists(queuePath(globalPmRoot));return raw===null||raw.trim().length===0?[]:parseQueueLines(raw)}async function removeFlushedEntriesFromCurrentQueue(globalPmRoot,flushedIds,retentionDays){return withQueueMutation(async()=>{const currentEntries=await readCurrentQueueEntries(globalPmRoot),{entries:retainedEntries}=pruneExpiredQueueEntries(currentEntries,retentionDays),remaining=retainedEntries.filter(entry=>!flushedIds.has(entry.event.event_id));return await rewriteQueue(globalPmRoot,remaining),remaining},globalPmRoot)}async function markFailedEntriesInCurrentQueue(globalPmRoot,failedIds,attemptTime,retentionDays){return withQueueMutation(async()=>{const currentEntries=await readCurrentQueueEntries(globalPmRoot),{entries:retainedEntries}=pruneExpiredQueueEntries(currentEntries,retentionDays),retried=retainedEntries.map(entry=>{if(!failedIds.has(entry.event.event_id))return entry;const attempts=entry.attempts+1;return{...entry,attempts,last_attempt_at:attemptTime,next_attempt_after:nextRetryIso(attempts)}});return await rewriteQueue(globalPmRoot,retried),retried},globalPmRoot)}async function flushQueue(globalPmRoot,endpoint,retentionDays){await cleanupTelemetryQueueTempOrphans(globalPmRoot);const normalizedEndpoint=endpoint.trim();if(normalizedEndpoint.length===0)return;const raw=await readFileIfExists(queuePath(globalPmRoot));if(raw===null||raw.trim().length===0){await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:0});return}const queueEntries=parseQueueLines(raw);if(queueEntries.length===0){await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:0});return}const{entries:retainedEntries,prunedCount}=pruneExpiredQueueEntries(queueEntries,retentionDays);if(retainedEntries.length===0){const remaining=await removeFlushedEntriesFromCurrentQueue(globalPmRoot,new Set,retentionDays);await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:remaining.length});return}const dueEntries=retainedEntries.filter(entry=>isDueForRetry(entry)).slice(0,TELEMETRY_FLUSH_BATCH_SIZE);if(dueEntries.length===0){const remaining=prunedCount>0?await removeFlushedEntriesFromCurrentQueue(globalPmRoot,new Set,retentionDays):retainedEntries;await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:remaining.length});return}const dueIds=new Set(dueEntries.map(entry=>entry.event.event_id)),attemptTime=nowIso(),requestHeaders={"content-type":"application/json"},ingestKey=process.env.PM_TELEMETRY_INGEST_KEY?.trim();ingestKey&&(requestHeaders["x-pm-telemetry-key"]=ingestKey);try{const status=await postTelemetryJson(normalizedEndpoint,requestHeaders,JSON.stringify({schema_version:TELEMETRY_SCHEMA_VERSION,events:dueEntries.map(entry=>entry.event)}));if(status<200||status>=300)throw new Error(`telemetry_flush_http_${status}`)}catch(error){const retried=await markFailedEntriesInCurrentQueue(globalPmRoot,dueIds,attemptTime,retentionDays),errorMessage=error instanceof Error?sanitizeString(error.message,"redacted"):"telemetry_flush_failed";await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:retried.length,last_attempted_flush_at:attemptTime,last_failed_flush_at:attemptTime,last_failed_flush_error:errorMessage});return}try{const remaining=await removeFlushedEntriesFromCurrentQueue(globalPmRoot,dueIds,retentionDays);await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:remaining.length,last_attempted_flush_at:attemptTime,last_successful_flush_at:attemptTime,last_failed_flush_at:void 0,last_failed_flush_error:void 0})}catch(error){const errorMessage=error instanceof Error?sanitizeString(error.message,"redacted"):"telemetry_flush_failed",currentEntries=await readCurrentQueueEntries(globalPmRoot).catch(()=>retainedEntries);await writeRuntimeState(globalPmRoot,{endpoint:normalizedEndpoint,queue_entries:currentEntries.length,last_attempted_flush_at:attemptTime,last_failed_flush_at:attemptTime,last_failed_flush_error:errorMessage})}}async function acquireTelemetryFlushLock(globalPmRoot){const lockPath=flushLockPath(globalPmRoot);parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV])||await mkdir(path.dirname(lockPath),{recursive:!0});try{return await mkdir(lockPath),!0}catch(error){if(typeof error!="object"||error===null||!("code"in error)||error.code!=="EEXIST")throw error}try{const lockStats=await stat(lockPath);return Date.now()-lockStats.mtimeMs<TELEMETRY_FLUSH_LOCK_STALE_MS?!1:(await rm(lockPath,{recursive:!0,force:!0}),await mkdir(lockPath),!0)}catch{return!1}}function isFreshDirectoryLock(lockPath,staleMs){try{return Date.now()-statSync(lockPath).mtimeMs<staleMs}catch{return!1}}function removeDirectoryLockBestEffort(lockPath){try{rmSync(lockPath,{recursive:!0,force:!0})}catch{}}function errorCode(error){if(typeof error!="object"||error===null||!("code"in error))return;const code=error.code;return typeof code=="string"?code:void 0}function createDirectoryLock(lockPath){try{return mkdirSync(lockPath),!0}catch(error){if(errorCode(error)==="EEXIST"||!isFileMissingError(error))return!1}try{return mkdirSync(path.dirname(lockPath),{recursive:!0}),mkdirSync(lockPath),!0}catch{return!1}}function acquireTelemetryFlushSpawnGate(globalPmRoot){if(isFreshDirectoryLock(flushLockPath(globalPmRoot),TELEMETRY_FLUSH_LOCK_STALE_MS))return!1;const lockPath=flushSpawnLockPath(globalPmRoot);try{if(Date.now()-statSync(lockPath).mtimeMs<TELEMETRY_FLUSH_SPAWN_LOCK_STALE_MS)return!1;removeDirectoryLockBestEffort(lockPath)}catch(error){if(!isFileMissingError(error))return!1}return createDirectoryLock(lockPath)}function releaseTelemetryFlushSpawnGate(globalPmRoot){removeDirectoryLockBestEffort(flushSpawnLockPath(globalPmRoot))}const _testOnly={acquireTelemetryFlushSpawnGate,acquireTelemetryFlushLock,buildAuthorContextPayloadFields,buildCommandErrorPayload,buildCommandFinishPayload,buildCommandStartPayload,buildOtelSpanRequest,createDirectoryLock,enqueuePendingOtelSpan,enqueueTelemetryEvent,errorCode,flushPendingOtelSpans,flushQueue,flushQueueWithProcessLock,flushTelemetryArtifacts,hashTelemetryErrorFingerprint,hashTelemetryValue,isEmailDomainCharacter,isEmailLocalCharacter,isExpiredPendingOtelSpan,isExpiredQueueEntry,isFreshDirectoryLock,isDueForRetry,isDueForRetryAt,isRetryableQueueRewriteError,looksLikeEmailToken,otelSpansQueuePath,parseBooleanTrueLike,postTelemetryJson,parsePendingOtelSpanLines,prunePendingOtelSpans,reconcilePendingOtelSpansAfterFlush,retentionCutoffMs,resolveOtelTracesEndpoint,resolveTelemetryHttpTimeoutMs,rewritePendingOtelSpans,normalizeForHash,normalizeCaptureLevel,normalizePmVersion,normalizeTelemetryErrorCategory,normalizeTelemetryErrorCode,normalizeTelemetryExitCode,parseQueueLines,pruneExpiredQueueEntries,readRuntimeState,readCurrentQueueEntries,releaseTelemetryFlushSpawnGate,removeFlushedEntriesFromCurrentQueue,removeDirectoryLockBestEffort,resolveTelemetrySourceContext,rewriteQueue,sanitizeCommandArgs,sanitizeStringMax,sanitizeStringRedacted,sanitizeValue,scheduleTelemetryFlush,shouldFlushInline,sleep,summarizeResult,telemetryFlushRunnerPath,withQueueMutation,flushLockPath,flushSpawnLockPath,runtimeStatePath,writeRuntimeState};async function flushQueueWithProcessLock(globalPmRoot,endpoint,retentionDays){const acquired=await acquireTelemetryFlushLock(globalPmRoot);if(releaseTelemetryFlushSpawnGate(globalPmRoot),!acquired)return!1;try{await flushTelemetryArtifacts(globalPmRoot,endpoint,retentionDays)}finally{try{await rm(flushLockPath(globalPmRoot),{recursive:!0,force:!0})}catch{}}return!0}async function dueTelemetryArtifactIds(globalPmRoot,retentionDays){const ids=new Set;try{const{entries}=pruneExpiredQueueEntries(await readCurrentQueueEntries(globalPmRoot),retentionDays);for(const entry of entries.filter(isDueForRetry))ids.add(`event:${entry.event.event_id}`)}catch{}try{const raw=await readFileIfExists(otelSpansQueuePath(globalPmRoot));if(raw!==null)for(const entry of prunePendingOtelSpans(parsePendingOtelSpanLines(raw),retentionDays).entries)isDueForRetryAt(entry.next_attempt_after)&&ids.add(`span:${entry.id}`)}catch{}return ids}function scheduleTelemetryFlush(globalPmRoot,endpoint,retentionDays){if(!isConfigurationOnlySettingsRead(globalPmRoot)){if(shouldFlushInline())return _lastFlushPromise=_lastFlushPromise.then(()=>flushTelemetryArtifacts(globalPmRoot,endpoint,retentionDays)),_lastFlushPromise;try{if(!acquireTelemetryFlushSpawnGate(globalPmRoot))return;const child=spawn(process.execPath,[telemetryFlushRunnerPath()],{detached:!0,stdio:"ignore",cwd:os.tmpdir(),env:{...process.env,PM_GLOBAL_PATH:globalPmRoot,[PM_TELEMETRY_FLUSH_CHILD_ENV]:"1"}});child.on("error",()=>{releaseTelemetryFlushSpawnGate(globalPmRoot)}),child.unref()}catch{releaseTelemetryFlushSpawnGate(globalPmRoot)}}}async function flushTelemetryQueueNow(globalPmRoot=resolveGlobalPmRoot(process.cwd())){if(!resolveTelemetryEnvironmentPolicy().telemetry_disabled)try{await runWithConfigurationOnlySettings(globalPmRoot,async()=>{const detached=parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV]);let continueDraining=!0;for(;continueDraining;){if(!(await readSettings(globalPmRoot)).telemetry.enabled)return;const installation=await withQueueMutation(()=>ensureInstallationId(globalPmRoot),globalPmRoot);if(!installation)return;const before=detached?await dueTelemetryArtifactIds(globalPmRoot,installation.retentionDays):new Set;if(!await flushQueueWithProcessLock(globalPmRoot,installation.endpoint,installation.retentionDays)||!detached)return;const after=await dueTelemetryArtifactIds(globalPmRoot,installation.retentionDays);continueDraining=after.size>0&&(after.size!==before.size||[...after].some(id=>!before.has(id)))}},()=>parseBooleanTrueLike(process.env[PM_TELEMETRY_FLUSH_CHILD_ENV]))}catch{}}async function startTelemetryCommand(context){if(resolveTelemetryEnvironmentPolicy().telemetry_disabled||context.command==="telemetry"&&context.args.some(token=>token.trim().toLowerCase()==="clear"))return null;try{const globalPmRoot=resolveGlobalPmRoot(process.cwd());if(!(await readSettings(globalPmRoot)).telemetry.enabled)return null;const coreReadOwned=context.global.noExtensions===!0||isActiveCommandUnextended(context.command),activeCommand=await withQueueMutation(async()=>{const installation=await ensureInstallationId(globalPmRoot);if(!installation)return null;const{installationId,endpoint,retentionDays,captureLevel}=installation,pmVersion=normalizePmVersion(context.pm_version),sourceContext=resolveTelemetrySourceContext(context.global),pmRootHash=hashWithInstallationId(installationId,context.pm_root),cwdHash=hashWithInstallationId(installationId,process.cwd()),otelTracesEndpoint=resolveOtelTracesEndpoint(),occurredAt=nowIso(),event={schema_version:TELEMETRY_SCHEMA_VERSION,event_id:crypto.randomUUID(),event_type:"command_start",occurred_at:occurredAt,installation_id:installationId,session_id:PROCESS_SESSION_ID,command:context.command,payload:buildCommandStartPayload({captureLevel,context,pmVersion,sourceContext,pmRootHash,cwdHash,installationId})},sampleRate=await resolveAutomaticReadSampleRate(globalPmRoot,context.command,coreReadOwned);sampleRate===1&&await appendTelemetryEvent(globalPmRoot,event);const commandTaxonomy=deriveTelemetryCommandTaxonomy(context.command),active={...sampleRate<1?{sample_rate:sampleRate}:{},started_at:occurredAt,started_at_ms:Date.now(),command:context.command,command_taxonomy:commandTaxonomy,pm_version:pmVersion,source_context:sourceContext.source_context,source_context_source:sourceContext.source_context_source,installation_id:installationId,pm_root_hash:pmRootHash,cwd_hash:cwdHash,endpoint,retention_days:retentionDays,global_pm_root:globalPmRoot,capture_level:captureLevel,otel_traces_endpoint:otelTracesEndpoint??void 0,otel_trace_id:otelTracesEndpoint?crypto.randomBytes(16).toString("hex"):void 0,otel_span_id:otelTracesEndpoint?crypto.randomBytes(8).toString("hex"):void 0};return sampleRate<1&&deferredReadStarts.set(active,event),active},globalPmRoot,TELEMETRY_FOREGROUND_LOCK_WAIT_MS);return activeCommand&&activeCommand.sample_rate===void 0&&scheduleTelemetryFlush(globalPmRoot,activeCommand.endpoint,activeCommand.retention_days),activeCommand}catch{return null}}async function finishTelemetryCommand(activeCommand,outcome){if(!(!activeCommand||resolveTelemetryEnvironmentPolicy().telemetry_disabled))try{if(!await withQueueMutation(async()=>{const settings=await readSettings(activeCommand.global_pm_root);if(resolveTelemetryEnvironmentPolicy().telemetry_disabled||!settings.telemetry.enabled||settings.telemetry.installation_id!==activeCommand.installation_id)return deferredReadStarts.delete(activeCommand),!1;const deferredStart=deferredReadStarts.get(activeCommand),sampleRate=outcome.ok?activeCommand.sample_rate??1:1;if(deferredStart){if(deferredReadStarts.delete(activeCommand),crypto.randomBytes(6).readUIntBE(0,6)/281474976710656>=sampleRate)return!1;deferredStart.payload.sample_rate=sampleRate,await appendTelemetryEvent(activeCommand.global_pm_root,deferredStart)}const finishedAt=nowIso(),durationMs=Math.max(0,Date.now()-activeCommand.started_at_ms),normalizedErrorCode=normalizeTelemetryErrorCode(inferTelemetryErrorCode({ok:outcome.ok,errorCode:outcome.error_code,errorMessage:outcome.error,exitCode:outcome.exit_code})),normalizedErrorCategory=normalizeTelemetryErrorCategory({ok:outcome.ok,errorCode:normalizedErrorCode,errorCategory:outcome.error_category}),normalizedExitCode=normalizeTelemetryExitCode(outcome.exit_code,outcome.ok),commandResolution=outcome.command_resolution??deriveTelemetryCommandResolution({ok:outcome.ok,errorCode:normalizedErrorCode,errorCategory:normalizedErrorCategory}),resolutionStage=outcome.resolution_stage??"execute",event={schema_version:TELEMETRY_SCHEMA_VERSION,event_id:crypto.randomUUID(),event_type:"command_finish",occurred_at:finishedAt,installation_id:activeCommand.installation_id,session_id:PROCESS_SESSION_ID,command:activeCommand.command,payload:{...deferredStart?{sample_rate:sampleRate}:{},...buildCommandFinishPayload({captureLevel:activeCommand.capture_level,pmVersion:activeCommand.pm_version,sourceContext:{source_context:activeCommand.source_context,source_context_source:activeCommand.source_context_source},outcome,durationMs,startedAt:activeCommand.started_at,command:activeCommand.command,installationId:activeCommand.installation_id,commandTaxonomy:activeCommand.command_taxonomy,exitCode:normalizedExitCode,errorCode:normalizedErrorCode,errorCategory:normalizedErrorCategory,commandResolution,resolutionStage})}};await appendTelemetryEvent(activeCommand.global_pm_root,event);const otelRequest=buildOtelSpanRequest(activeCommand,{...outcome,exit_code:normalizedExitCode,error_code:normalizedErrorCode,error_category:normalizedErrorCategory},finishedAt,durationMs,sampleRate);return otelRequest&&await appendPendingOtelSpan(activeCommand.global_pm_root,otelRequest),!0},activeCommand.global_pm_root,TELEMETRY_FOREGROUND_LOCK_WAIT_MS))return;await scheduleTelemetryFlush(activeCommand.global_pm_root,activeCommand.endpoint,activeCommand.retention_days)}catch{}}async function emitTelemetryErrorEvent(context){if(!resolveTelemetryEnvironmentPolicy().telemetry_disabled)try{const globalPmRoot=resolveGlobalPmRoot(process.cwd());if(!(await readSettings(globalPmRoot)).telemetry.enabled)return;const captured=await withQueueMutation(async()=>{const installation=await ensureInstallationId(globalPmRoot);if(!installation)return null;const{installationId,captureLevel}=installation,pmVersion=normalizePmVersion(context.pm_version),sourceContext=resolveTelemetrySourceContext(context.global),pmRootHash=hashWithInstallationId(installationId,context.pm_root),cwdHash=hashWithInstallationId(installationId,process.cwd()),occurredAt=nowIso(),normalizedErrorCode=normalizeTelemetryErrorCode(inferTelemetryErrorCode({ok:!1,errorCode:context.error_code,errorMessage:context.error_message,exitCode:context.exit_code})),normalizedErrorCategory=context.error_category??resolveTelemetryErrorCategory(normalizedErrorCode),normalizedExitCode=normalizeTelemetryExitCode(context.exit_code,!1),normalizedCommand=context.command.trim().length>0?context.command:"<unknown>",commandTaxonomy=deriveTelemetryCommandTaxonomy(normalizedCommand),commandResolution=context.command_resolution??deriveTelemetryCommandResolution({ok:!1,errorCode:normalizedErrorCode,errorCategory:normalizedErrorCategory}),resolutionStage=context.resolution_stage??"unknown",event={schema_version:TELEMETRY_SCHEMA_VERSION,event_id:crypto.randomUUID(),event_type:"command_error",occurred_at:occurredAt,installation_id:installationId,session_id:PROCESS_SESSION_ID,command:sanitizeString(normalizedCommand,"redacted"),payload:buildCommandErrorPayload({captureLevel,pmVersion,sourceContext,command:normalizedCommand,commandTaxonomy,commandResolution,resolutionStage,args:context.args,options:context.options,pmRootHash,cwdHash,installationId,errorCode:normalizedErrorCode,errorCategory:normalizedErrorCategory,exitCode:normalizedExitCode,errorMessage:context.error_message})};return await appendTelemetryEvent(globalPmRoot,event),installation},globalPmRoot,TELEMETRY_FOREGROUND_LOCK_WAIT_MS);captured&&await scheduleTelemetryFlush(globalPmRoot,captured.endpoint,captured.retentionDays)}catch{}}export{PM_TELEMETRY_SOURCE_CONTEXT_VALUES2 as PM_TELEMETRY_SOURCE_CONTEXT_VALUES,TELEMETRY_MAX_QUEUE_ENTRY_ATTEMPTS,TELEMETRY_SCHEMA_VERSION,_testOnly,emitTelemetryErrorEvent,finishTelemetryCommand,flushTelemetryQueueNow,startTelemetryCommand,waitForPendingFlush,withQueueMutation as withTelemetryQueueMutation};
10
10
  //# sourceMappingURL=runtime.js.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @module sdk/governance/health/projection
3
+ *
4
+ * Pure health evidence projections shared by CLI, MCP and SDK diagnostics.
5
+ */
6
+ import type { HealthCheck,HealthResult,RunHealthOptions } from "../health.js";
7
+ /** Maximum detail sample retained by compact health projections. */
8
+ export declare const BRIEF_HEALTH_DETAIL_LIMIT = 8;
9
+ /** Maximum warning rows retained while blocking causes remain complete. */
10
+ export declare const HEALTH_WARNING_LIMIT = 100;
11
+ /** Return bounded string detail and report whether values were withheld. */
12
+ export declare function summarizeList(values:string[],limit:number):{
13
+ values:string[];
14
+ truncated:boolean;
15
+ };
16
+ /** Count arbitrary rows while bounding the retained evidence sample. */
17
+ export declare function summarizeRecordList(value:unknown,limit:number):{
18
+ count:number;
19
+ sample:unknown[];
20
+ truncated:boolean;
21
+ };
22
+ /** Bound extension identity samples without retaining executable registrations. */
23
+ export declare function summarizeExtensionList(value:unknown,limit:number):{
24
+ count:number;
25
+ sample:unknown[];
26
+ truncated:boolean;
27
+ };
28
+ /** Count string warnings and retain a bounded sample for diagnostic output. */
29
+ export declare function summarizeStringList(value:unknown,limit:number):{
30
+ count:number;
31
+ sample:string[];
32
+ truncated:boolean;
33
+ };
34
+ /** Summarize one health check using its diagnostic-specific detail contract. */
35
+ export declare function summarizeHealthCheckDetails(check:HealthCheck,limit:number):Record<string,unknown>;
36
+ /** Bound health warnings and select evidence without changing the computed verdict. */
37
+ export declare function projectHealthResult(result:HealthResult,options:RunHealthOptions,summaryMode:boolean):HealthResult;
@@ -0,0 +1,2 @@
1
+ (function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="717434ef-3c62-50a8-8887-e2bbc3851eff")}catch{}})();const BRIEF_HEALTH_DETAIL_LIMIT=8,HEALTH_WARNING_LIMIT=100;function summarizeList(values,limit){return values.length<=limit?{values,truncated:!1}:{values:values.slice(0,limit),truncated:!0}}function summarizeRecordList(value,limit){return Array.isArray(value)?{count:value.length,sample:value.slice(0,limit),truncated:value.length>limit}:{count:0,sample:[],truncated:!1}}function summarizeExtensionRecord(value){if(typeof value!="object"||value===null||Array.isArray(value))return{};const record=value;return{layer:record.layer,directory:record.directory,name:record.name,version:record.version,enabled:record.enabled,status:record.status,has_activate:record.has_activate,capabilities:record.capabilities}}function summarizeExtensionList(value,limit){const summary=summarizeRecordList(value,limit);return{...summary,sample:summary.sample.map(entry=>summarizeExtensionRecord(entry))}}function summarizeStringList(value,limit){if(!Array.isArray(value))return{count:0,sample:[],truncated:!1};const strings=value.filter(entry=>typeof entry=="string");return{count:strings.length,sample:strings.slice(0,limit),truncated:strings.length>limit}}function summarizeActivationMigrationStatus(value){if(typeof value!="object"||value===null)return null;const status=value;return{applied_count:status.applied_count,pending_count:status.pending_count,failed_count:status.failed_count}}const HEALTH_DETAIL_SUMMARIZERS={settings:(details,limit)=>({version:details.version,id_prefix:details.id_prefix,locks_ttl_seconds:details.locks_ttl_seconds,warnings:summarizeStringList(details.warnings,limit)}),directories:(details,limit)=>({required_count:Array.isArray(details.required)?details.required.length:0,optional_count:Array.isArray(details.optional)?details.optional.length:0,missing_required:summarizeStringList(details.missing_required,limit),missing_optional:summarizeStringList(details.missing_optional,limit),missing:summarizeStringList(details.missing,limit),strict_directories:details.strict_directories}),settings_values:(details,limit)=>({warnings:summarizeStringList(details.warnings,limit)}),telemetry:details=>({enabled:details.enabled,capture_level:details.capture_level,endpoint:details.endpoint,queue_exists:details.queue_exists,queue_entries:details.queue_entries,queue_draining:details.queue_draining,queue_invalid_rows:details.queue_invalid_rows,queue_rows_total:details.queue_rows_total,last_successful_flush_at:details.last_successful_flush_at,last_failed_flush_at:details.last_failed_flush_at,endpoint_probe:details.endpoint_probe,env_overrides:details.env_overrides}),extensions:(details,limit)=>{const activation=typeof details.activation=="object"&&details.activation!==null?details.activation:{};return{disabled_by_flag:details.disabled_by_flag,discovered:summarizeExtensionList(details.discovered,limit),effective:summarizeExtensionList(details.effective,limit),loaded:summarizeExtensionList(details.loaded,limit),failed:summarizeRecordList(details.failed,limit),warnings:summarizeStringList(details.warnings,limit),activation:{failed:summarizeRecordList(activation.failed,limit),warnings:summarizeStringList(activation.warnings,limit),hook_counts:activation.hook_counts,command_handler_count:activation.command_handler_count,service_override_count:activation.service_override_count,renderer_override_count:activation.renderer_override_count,registration_counts:activation.registration_counts,migration_status:summarizeActivationMigrationStatus(activation.migration_status)},author_manifest:details.author_manifest,triage:details.triage,capability_contract:details.capability_contract,capability_guidance:summarizeRecordList(details.capability_guidance,limit),host_version_census:details.host_version_census}},storage:(details,limit)=>{const authorAttribution=typeof details.author_attribution=="object"&&details.author_attribution!==null?details.author_attribution:void 0;return{...details,...authorAttribution?{author_attribution:{...authorAttribution,affected_item_ids:summarizeStringList(authorAttribution.affected_item_ids,limit),samples:summarizeRecordList(authorAttribution.samples,limit)}}:{}}},locks:details=>({active_lock_count:details.active_lock_count,stale_lock_count:details.stale_lock_count,unreadable_lock_count:details.unreadable_lock_count,unparseable_lock_count:details.unparseable_lock_count}),integrity:(details,limit)=>{const trackedRuntimeCache=typeof details.tracked_runtime_cache=="object"&&details.tracked_runtime_cache!==null?details.tracked_runtime_cache:void 0;return{checked_item_files:details.checked_item_files,checked_history_streams:details.checked_history_streams,counts:details.counts,item_unreadable:summarizeStringList(details.item_unreadable,limit),item_conflict_markers:summarizeRecordList(details.item_conflict_markers,limit),item_parse_failures:summarizeStringList(details.item_parse_failures,limit),tracked_runtime_cache:trackedRuntimeCache===void 0?details.tracked_runtime_cache:{...trackedRuntimeCache,tracked_paths:summarizeStringList(trackedRuntimeCache.tracked_paths,limit)},history_unreadable:summarizeStringList(details.history_unreadable,limit),history_conflict_markers:summarizeRecordList(details.history_conflict_markers,limit),history_invalid_json:summarizeRecordList(details.history_invalid_json,limit),skipped:details.skipped}},history_drift:(details,limit)=>{const cacheConfirmation=typeof details.cache_confirmation=="object"&&details.cache_confirmation!==null?details.cache_confirmation:void 0;return{checked_items:details.checked_items,cache_hit_verification:details.cache_hit_verification,cache_confirmation:cacheConfirmation===void 0?details.cache_confirmation:{...cacheConfirmation,candidate_items:summarizeStringList(cacheConfirmation.candidate_items,limit),confirmed_items:summarizeStringList(cacheConfirmation.confirmed_items,limit),resolved_false_positive_items:summarizeStringList(cacheConfirmation.resolved_false_positive_items,limit)},counts:details.counts,drifted_items:summarizeStringList(details.drifted_items,limit),merge_receipt_attributed_items:summarizeStringList(details.merge_receipt_attributed_items,limit),missing_streams:summarizeStringList(details.missing_streams,limit),unreadable_streams:summarizeStringList(details.unreadable_streams,limit),hash_mismatches:summarizeStringList(details.hash_mismatches,limit),chain_mismatches:summarizeStringList(details.chain_mismatches,limit),version_skews:summarizeStringList(details.version_skews,limit),workspace_state_mismatches:summarizeStringList(details.workspace_state_mismatches,limit),workspace_state_missing:summarizeStringList(details.workspace_state_missing,limit),workspace_state_unreadable:summarizeStringList(details.workspace_state_unreadable,limit),skipped:details.skipped}},vectorization:(details,limit)=>({semantic_runtime_available:details.semantic_runtime_available,compatibility_mode_auto_defaults:details.compatibility_mode_auto_defaults,auto_ollama_defaults_applied:details.auto_ollama_defaults_applied,auto_ollama_defaults_skipped_reason:details.auto_ollama_defaults_skipped_reason,auto_ollama_defaults_remediation:details.auto_ollama_defaults_remediation,refresh_policy:details.refresh_policy,provider_active:details.provider_active,vector_store_active:details.vector_store_active,items:details.items,ledger_entries_before:details.ledger_entries_before,stale_items_before_total:details.stale_items_before_total,stale_items_before:summarizeStringList(details.stale_items_before,limit),refresh_attempted:details.refresh_attempted,refresh_skipped_reason:details.refresh_skipped_reason,refresh_result:details.refresh_result,ledger_entries_after:details.ledger_entries_after,stale_items_after_total:details.stale_items_after_total,stale_items_after:summarizeStringList(details.stale_items_after,limit),skipped:details.skipped})};function summarizeHealthCheckDetails(check,limit){const summarize=HEALTH_DETAIL_SUMMARIZERS[check.name];return summarize?summarize(check.details,limit):check.details}function summarizeHealthyExtensionDetails(check){return{disabled_by_flag:check.details.disabled_by_flag,loaded_count:Array.isArray(check.details.loaded)?check.details.loaded.length:0,failed_count:0,warning_count:0,restore_with:"pm health --full"}}function boundedHealthCheckDetails(check){if(check.name==="extensions"&&check.status==="ok")return summarizeHealthyExtensionDetails(check);const summarized=summarizeHealthCheckDetails(check,8);return Buffer.byteLength(JSON.stringify(summarized))<Buffer.byteLength(JSON.stringify(check.details))?summarized:check.details}function retainHealthFindings(result,warnings){const retained=new Set([...warnings,...result.failed_because]);return(result.findings??[]).filter(finding=>retained.has(finding.warning))}function applyBriefHealthProjection(result){const warningsSummary=summarizeStringList(result.warnings,8);return{ok:result.ok,...result.verdict?{verdict:result.verdict}:{},checks:result.checks.map(check=>({name:check.name,status:check.status,ok:check.ok,details:boundedHealthCheckDetails(check)})),warnings:warningsSummary.sample,findings:retainHealthFindings(result,warningsSummary.sample),failed_because:result.failed_because,projection:{mode:"brief",warning_count:warningsSummary.count,warnings_truncated:warningsSummary.truncated,detail_limit:8},generated_at:result.generated_at}}function isSkippedHealthCheck(check){return check.details.skipped===!0}function applySummaryHealthProjection(result){const warningsSummary=summarizeStringList(result.warnings,8),omittedChecks=result.checks.filter(isSkippedHealthCheck).map(check=>check.name);return{ok:result.ok,...result.verdict?{verdict:result.verdict}:{},checks:result.checks.filter(check=>!isSkippedHealthCheck(check)).map(check=>({name:check.name,status:check.status,ok:check.ok,details:{}})),warning_count:warningsSummary.count,warnings:warningsSummary.sample,findings:retainHealthFindings(result,warningsSummary.sample),failed_because:result.failed_because,projection:{mode:"summary",warning_count:warningsSummary.count,warnings_truncated:warningsSummary.truncated,detail_limit:8,omitted_checks:omittedChecks},generated_at:result.generated_at}}function selectHealthProjection(result,options,summaryMode){return options.full===!0?result:summaryMode?applySummaryHealthProjection(result):options.brief===!0?applyBriefHealthProjection(result):{...result,checks:result.checks.map(check=>check.name==="extensions"&&check.status==="ok"?{...check,details:summarizeHealthyExtensionDetails(check)}:check),projection:{mode:"standard",warning_count:result.warning_count,warnings_truncated:result.warnings_truncated===!0,detail_limit:8}}}function projectHealthResult(result,options,summaryMode){const warningCount=result.warning_count??result.warnings.length,warnings=result.warnings.slice(0,100),boundedResult={...result,warning_count:warningCount,warning_limit:100,warnings_truncated:warningCount>100,warnings,findings:retainHealthFindings(result,warnings)},projected=selectHealthProjection(boundedResult,options,summaryMode);return{...projected,warning_count:warningCount,warning_limit:100,warnings_truncated:warningCount>projected.warnings.length,...projected.projection?{projection:{...projected.projection,warning_count:warningCount,warnings_truncated:warningCount>projected.warnings.length}}:{}}}export{BRIEF_HEALTH_DETAIL_LIMIT,HEALTH_WARNING_LIMIT,projectHealthResult,summarizeExtensionList,summarizeHealthCheckDetails,summarizeList,summarizeRecordList,summarizeStringList};
2
+ //# sourceMappingURL=projection.js.map
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @module sdk/governance/health
3
+ *
4
+ * Implements the pm health command surface and its agent-facing runtime behavior.
5
+ */
6
+ import { projectHealthResult,summarizeExtensionList,summarizeHealthCheckDetails,summarizeRecordList,summarizeStringList } from "./health/projection.js";
1
7
  import { resolveEmbeddingProviders } from "../../core/search/providers.js";
2
8
  import { resolveSettingsWithSemanticRuntimeDefaults } from "../../core/search/semantic-defaults.js";
3
9
  import { buildVectorizationEmbeddingIdentity } from "../../core/search/vectorization-metadata.js";
@@ -67,7 +73,7 @@ findings:HealthFinding[];
67
73
  failed_because:string[];
68
74
  /** Value that configures or reports projection for this contract. */
69
75
  projection?:{
70
- mode:"brief" | "summary" | "full";
76
+ mode:"standard" | "brief" | "summary" | "full";
71
77
  warning_count:number;
72
78
  warnings_truncated:boolean;
73
79
  detail_limit:number;
@@ -163,22 +169,6 @@ declare function isDirectory(targetPath:string):Promise<boolean>;
163
169
  declare function listItemDocumentPaths(pmRoot:string,typeToFolder:Record<string,string>):Promise<string[]>;
164
170
  declare function buildHierarchyIntegrityWarnings(analysis:HierarchyIntegrityAnalysis):string[];
165
171
  declare function buildExtensionHealthTriageSummary(warnings:string[],loadFailureCount:number,activationFailureCount:number,migrationStatus:MigrationStatusSummary,managedStateWarningCount:number,managedExtensionEntriesCount:number,unmanagedLoadedExtensions:string[],unmanagedExpectedExtensions:string[],unmanagedActionRequiredExtensions:string[]):ExtensionHealthTriageSummary;
166
- declare function summarizeRecordList(value:unknown,limit:number):{
167
- count:number;
168
- sample:unknown[];
169
- truncated:boolean;
170
- };
171
- declare function summarizeExtensionList(value:unknown,limit:number):{
172
- count:number;
173
- sample:unknown[];
174
- truncated:boolean;
175
- };
176
- declare function summarizeStringList(value:unknown,limit:number):{
177
- count:number;
178
- sample:string[];
179
- truncated:boolean;
180
- };
181
- declare function summarizeHealthCheckDetails(check:HealthCheck,limit:number):Record<string,unknown>;
182
172
  declare function selectStaleItemDetail(values:string[],verboseStaleItems:boolean):{
183
173
  values:string[];
184
174
  truncated:boolean;
@@ -230,7 +220,6 @@ checks:HealthCheck[];
230
220
  remediationSources:Record<HealthCheck["name"],string[]>;
231
221
  requireMergeDrivers:boolean;
232
222
  }):HealthFinding[];
233
- declare function projectHealthResult(result:HealthResult,options:RunHealthOptions,summaryMode:boolean):HealthResult;
234
223
  /** Inspect tracker integrity and runtime configuration, keeping optional guidance and telemetry failures diagnostic. */
235
224
  export declare function runHealth(global:GlobalOptions,options?:RunHealthOptions):Promise<HealthResult>;
236
225
  /** Public contract for test only health command, shared by SDK and presentation-layer consumers. */