@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +25 -0
- package/dist/cli/register-list-query.js +2 -2
- package/dist/cli-bundle/bundle-manifest.json +1 -1
- package/dist/cli-bundle/chunks/{chunk-3QKI3XNX.js → chunk-4GA4MUTE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-X2ONXFBP.js → chunk-4V6ONLI6.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-B5QVGCZX.js → chunk-6VZKYJW7.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-7PATQWTH.js +20 -0
- package/dist/cli-bundle/chunks/{chunk-W3KZ22DW.js → chunk-7WIEAGDS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-EA2CG7UM.js → chunk-AETP4JEM.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-6ZDKKOKM.js → chunk-FIJOSX2C.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-VMCSTFSO.js → chunk-LUKVNL72.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-J4LPQCET.js → chunk-OJ77ZQN3.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-O4YBC3OM.js → chunk-PYRREEUB.js} +30 -30
- package/dist/cli-bundle/chunks/chunk-RHQJ6VWC.js +237 -0
- package/dist/cli-bundle/chunks/{chunk-OZCSXX4D.js → chunk-RNABUEFB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HY7FQ7QX.js → chunk-TO6CIV4C.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JS3B2M4D.js → chunk-ZZED447K.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-RU3QZSAQ.js → register-list-query-PUCVYYBD.js} +7 -7
- package/dist/cli-bundle/chunks/{register-mutation-EQYMT32A.js → register-mutation-GGGVBXD5.js} +2 -2
- package/dist/cli-bundle/chunks/{register-operations-VXBGE4XI.js → register-operations-NRZ6Q4QE.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-UUDEGFRO.js → register-setup-MV3P3YSF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-LDKX4KYJ.js → chunk-2MPQUMTF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-MBQF6HT6.js → chunk-5UKCSZWT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-FTUZ3JF2.js → chunk-A4ZHHTEX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-JXR6UKFM.js → chunk-B4YLP5ZB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-NZO7GOXD.js → chunk-BFEMT5U3.js} +16 -16
- package/dist/cli-bundle/focused-chunks/{chunk-QOSVJDOO.js → chunk-FW7CSSKL.js} +61 -61
- package/dist/cli-bundle/focused-chunks/{chunk-AH6NX6GM.js → chunk-HYPRPSYD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RBLSY6ML.js → chunk-IRVL4UXR.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-RHTH5ILM.js → chunk-L55KQ2KT.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-PYC7BF6Z.js → chunk-MASIOFPG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-RJ3EIHDU.js +26 -0
- package/dist/cli-bundle/focused-chunks/chunk-SEL4Z2OO.js +167 -0
- package/dist/cli-bundle/focused-chunks/{chunk-2IOHHNRT.js → chunk-TB7F4FCR.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-UNTQE37U.js → chunk-TZUIBG3P.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-E33QA7PK.js → chunk-Z7YIFCNE.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-SIGIGZCG.js → chunk-ZDBS2DCT.js} +2 -2
- package/dist/cli-bundle/main.js +2 -2
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +16 -16
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +50 -49
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +1 -1
- package/dist/core/history/event-index.d.ts +8 -1
- package/dist/core/history/event-index.js +19 -18
- package/dist/core/item/item-format.js +1 -1
- package/dist/core/lock/lock.d.ts +8 -1
- package/dist/core/lock/lock.js +3 -3
- package/dist/core/output/output.js +2 -2
- package/dist/core/store/paths.js +1 -1
- package/dist/core/telemetry/policy.d.ts +2 -0
- package/dist/core/telemetry/policy.js +1 -1
- package/dist/core/telemetry/runtime.d.ts +5 -3
- package/dist/core/telemetry/runtime.js +3 -3
- package/dist/sdk/governance/health/projection.d.ts +37 -0
- package/dist/sdk/governance/health/projection.js +2 -0
- package/dist/sdk/governance/health.d.ts +7 -18
- package/dist/sdk/governance/health.js +2 -2
- package/dist/sdk/mutation-events.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/list.d.ts +2 -0
- package/dist/sdk/query/list.js +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +1 -1
- package/docs/COMMANDS.md +26 -0
- package/docs/CONFIGURATION.md +22 -1
- package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +22 -3
- package/docs/OUTPUT_PROJECTION_CONTRACTS.md +10 -0
- package/docs/RELEASING.md +8 -1
- package/docs/SDK_CONTEXT_COORDINATION.md +71 -7
- package/docs/SDK_STORAGE_LIFECYCLE.md +24 -2
- package/docs/TESTING.md +8 -0
- package/docs/examples/ci/github-actions-pm-extension-gate.yml +1 -1
- package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +1 -1
- package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +1 -1
- package/marketplace.json +1 -1
- package/node_modules/@opentelemetry/core/package.json +2 -1
- package/node_modules/@opentelemetry/instrumentation/package.json +2 -1
- package/node_modules/@opentelemetry/resources/package.json +2 -1
- package/node_modules/@opentelemetry/sdk-trace/package.json +2 -1
- package/node_modules/@opentelemetry/sdk-trace-base/package.json +2 -1
- package/node_modules/@sentry/core/build/cjs/client.js +5 -4
- package/node_modules/@sentry/core/build/cjs/tracing/ai/gen-ai-attributes.js +0 -4
- package/node_modules/@sentry/core/build/cjs/tracing/ai/utils.js +33 -23
- package/node_modules/@sentry/core/build/cjs/tracing/anthropic-ai/index.js +7 -6
- package/node_modules/@sentry/core/build/cjs/tracing/anthropic-ai/streaming.js +3 -1
- package/node_modules/@sentry/core/build/cjs/tracing/google-genai/index.js +13 -14
- package/node_modules/@sentry/core/build/cjs/tracing/google-genai/streaming.js +6 -1
- package/node_modules/@sentry/core/build/cjs/tracing/langchain/utils.js +71 -21
- package/node_modules/@sentry/core/build/cjs/tracing/langgraph/utils.js +23 -33
- package/node_modules/@sentry/core/build/cjs/tracing/openai/streaming.js +6 -0
- package/node_modules/@sentry/core/build/cjs/tracing/openai/utils.js +11 -0
- package/node_modules/@sentry/core/build/cjs/tracing/workers-ai/utils.js +1 -1
- package/node_modules/@sentry/core/build/cjs/utils/eventUtils.js +4 -0
- package/node_modules/@sentry/core/build/cjs/utils/prepareEvent.js +2 -2
- package/node_modules/@sentry/core/build/cjs/utils/version.js +1 -1
- package/node_modules/@sentry/core/build/esm/client.js +6 -5
- package/node_modules/@sentry/core/build/esm/package.json +1 -1
- package/node_modules/@sentry/core/build/esm/tracing/ai/gen-ai-attributes.js +1 -3
- package/node_modules/@sentry/core/build/esm/tracing/ai/utils.js +34 -24
- package/node_modules/@sentry/core/build/esm/tracing/anthropic-ai/index.js +8 -7
- package/node_modules/@sentry/core/build/esm/tracing/anthropic-ai/streaming.js +3 -1
- package/node_modules/@sentry/core/build/esm/tracing/google-genai/index.js +15 -16
- package/node_modules/@sentry/core/build/esm/tracing/google-genai/streaming.js +6 -1
- package/node_modules/@sentry/core/build/esm/tracing/langchain/utils.js +73 -24
- package/node_modules/@sentry/core/build/esm/tracing/langgraph/utils.js +24 -34
- package/node_modules/@sentry/core/build/esm/tracing/openai/streaming.js +6 -0
- package/node_modules/@sentry/core/build/esm/tracing/openai/utils.js +11 -0
- package/node_modules/@sentry/core/build/esm/tracing/workers-ai/utils.js +2 -2
- package/node_modules/@sentry/core/build/esm/utils/eventUtils.js +4 -1
- package/node_modules/@sentry/core/build/esm/utils/prepareEvent.js +2 -2
- package/node_modules/@sentry/core/build/esm/utils/version.js +1 -1
- package/node_modules/@sentry/core/build/types/tracing/ai/utils.d.ts +3 -7
- package/node_modules/@sentry/core/build/types/tracing/anthropic-ai/types.d.ts +2 -2
- package/node_modules/@sentry/core/build/types/tracing/langchain/types.d.ts +15 -0
- package/node_modules/@sentry/core/build/types/tracing/langchain/utils.d.ts +1 -0
- package/node_modules/@sentry/core/build/types/tracing/langgraph/utils.d.ts +2 -0
- package/node_modules/@sentry/core/build/types/tracing/openai/types.d.ts +2 -0
- package/node_modules/@sentry/core/build/types/utils/eventUtils.d.ts +2 -1
- package/node_modules/@sentry/core/build/types-ts3.8/tracing/ai/utils.d.ts +3 -7
- package/node_modules/@sentry/core/build/types-ts3.8/tracing/anthropic-ai/types.d.ts +2 -2
- package/node_modules/@sentry/core/build/types-ts3.8/tracing/langchain/types.d.ts +15 -0
- package/node_modules/@sentry/core/build/types-ts3.8/tracing/langchain/utils.d.ts +1 -0
- package/node_modules/@sentry/core/build/types-ts3.8/tracing/langgraph/utils.d.ts +2 -0
- package/node_modules/@sentry/core/build/types-ts3.8/tracing/openai/types.d.ts +2 -0
- package/node_modules/@sentry/core/build/types-ts3.8/utils/eventUtils.d.ts +2 -1
- package/node_modules/@sentry/core/package.json +1 -1
- package/node_modules/@sentry/node/build/esm/package.json +1 -1
- package/node_modules/@sentry/node/package.json +5 -5
- package/node_modules/@sentry/node-core/build/cjs/integrations/anr/index.js +1 -1
- package/node_modules/@sentry/node-core/build/cjs/integrations/local-variables/local-variables-async.js +1 -1
- package/node_modules/@sentry/node-core/build/esm/integrations/anr/index.js +1 -1
- package/node_modules/@sentry/node-core/build/esm/integrations/anr/worker-script.js +2 -2
- package/node_modules/@sentry/node-core/build/esm/integrations/local-variables/local-variables-async.js +1 -1
- package/node_modules/@sentry/node-core/build/esm/integrations/local-variables/worker-script.js +1 -1
- package/node_modules/@sentry/node-core/build/esm/package.json +1 -1
- package/node_modules/@sentry/node-core/package.json +10 -4
- package/node_modules/@sentry/opentelemetry/build/esm/package.json +1 -1
- package/node_modules/@sentry/opentelemetry/package.json +5 -2
- package/node_modules/@sentry/server-utils/build/THIRD-PARTY-LICENSES.txt +55 -55
- package/node_modules/@sentry/server-utils/build/esm/package.json +1 -1
- package/node_modules/@sentry/server-utils/package.json +2 -2
- package/node_modules/@toon-format/toon/README.md +10 -41
- package/node_modules/@toon-format/toon/dist/index.d.mts +12 -36
- package/node_modules/@toon-format/toon/dist/index.mjs +134 -202
- package/node_modules/@toon-format/toon/package.json +2 -2
- package/node_modules/debug/package.json +3 -0
- package/node_modules/fdir/package.json +3 -0
- package/node_modules/has-flag/index.d.ts +39 -0
- package/node_modules/has-flag/index.js +8 -0
- package/node_modules/has-flag/license +9 -0
- package/node_modules/has-flag/package.json +46 -0
- package/node_modules/has-flag/readme.md +89 -0
- package/node_modules/supports-color/browser.js +5 -0
- package/node_modules/supports-color/index.js +135 -0
- package/node_modules/supports-color/license +9 -0
- package/node_modules/supports-color/package.json +53 -0
- package/node_modules/supports-color/readme.md +76 -0
- package/package.json +4 -4
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/package.json +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/pm-codex/package.json +1 -1
- package/plugins/pm-codex/plugin.json +1 -1
- package/runtime-dependencies.json +1 -1
- package/dist/cli-bundle/chunks/chunk-4PNPDT2N.js +0 -236
- package/dist/cli-bundle/chunks/chunk-X53HM753.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-5JEFDEL3.js +0 -166
- package/dist/cli-bundle/focused-chunks/chunk-TRFVAWF2.js +0 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a3768d4b-d991-516e-91ff-7bd9373c192f")}catch{}})();import{encode as encodeToon}from"@toon-format/toon";import{isDeepStrictEqual}from"node:util";import{CONFIDENCE_TEXT_VALUES,ISSUE_SEVERITY_VALUES,PLAN_STEP_STATUS_VALUES,RECURRENCE_FREQUENCY_VALUES,RECURRENCE_WEEKDAY_VALUES,STATUS_VALUES,weekdayOrderIndex}from"../../types/index.js";import{coerceRuntimeFieldValue}from"../schema/runtime-field-values.js";import{resolveRuntimeFieldRegistry,resolveRuntimeStatusRegistry}from"../schema/runtime-schema.js";import{BASELINE_ITEM_FORMAT_VERSION,CURRENT_ITEM_FORMAT_VERSION,effectiveItemFormatVersion,normalizeItemFormatVersion}from"./item-format-version.js";import{normalizeStatusInput}from"./status.js";import{decodeToonItemContent}from"./toon-decode.js";import{EXIT_CODE,ITEM_METADATA_KEY_ORDER}from"../shared/constants.js";import{findFirstMergeConflictMarker}from"../shared/conflict-markers.js";import{PmCliError}from"../shared/errors.js";import{orderObject}from"../shared/serialization.js";import{compareTimestampStrings,isTimestampLiteral}from"../shared/time.js";import{coerceFiniteNumber}from"../shared/primitives.js";const LINKED_TEST_PM_CONTEXT_MODE_VALUES=new Set(["schema","tracker","auto","none"]),LINKED_TEST_WORKSPACE_CONTEXT_MODE_VALUES=new Set(["source","isolated","snapshot"]),LINKED_TEST_TRUST_REASON_VALUES=new Set(["legacy","local_mutation","local_source_ref","acknowledged","invalid_provenance","foreign_source_ref"]),ITEM_TEST_RUN_STATUS_VALUES=new Set(["passed","failed","stopped","canceled"]),PLAN_STEP_STATUS_SET=new Set(PLAN_STEP_STATUS_VALUES);function normalizePathValue(value){return value.replaceAll("\\","/")}function firstNonZeroComparison(comparisons){for(const comparison of comparisons)if(comparison!==0)return comparison;return 0}function deleteUndefinedFields(record){for(const[key,value]of Object.entries(record))value===void 0&&delete record[key]}const REQUIRED_STRING_FIELDS=["id","title","description","created_at","updated_at"],STATIC_ITEM_METADATA_FIELD_SET=new Set(ITEM_METADATA_KEY_ORDER);function resolveRuntimeSchemaValidationContext(options){if(options?.schema)return{statusRegistry:resolveRuntimeStatusRegistry(options.schema),fieldRegistry:resolveRuntimeFieldRegistry(options.schema),unknownFieldPolicy:options.schema.unknown_field_policy??"allow",extensionFieldNames:new Set(options.extensionFieldNames??[]),onWarning:options.onWarning}}function runtimeFieldRequiredForType(definition,typeName){return definition.required?definition.required_types.length===0?!0:definition.required_types.map(value=>value.toLowerCase()).includes(typeName.trim().toLowerCase()):!1}function validationError(message){const field=message.match(/^([a-z_][\w.]*)\s/u)?.[1];throw new PmCliError(`Invalid item metadata: ${message}`,EXIT_CODE.GENERIC_FAILURE,{code:"item_document_invalid",reason:message.includes("required")?"missing_required_field":"schema_validation_error",...field?{field}:{},required:"Provide an item document whose metadata satisfies the active runtime schema.",why:message})}function documentSyntaxError(format,message){throw new PmCliError(message,EXIT_CODE.GENERIC_FAILURE,{code:"item_document_invalid",reason:"syntax_error",format,required:`Provide a syntactically valid ${format==="toon"?"TOON":"JSON Markdown"} item document.`,why:"The document could not be decoded far enough to validate item metadata."})}function assertSupportedItemFormat(metadata,required){if(!required||typeof metadata!="object"||metadata===null)return;const formatVersion=effectiveItemFormatVersion(metadata);if(!(formatVersion<=CURRENT_ITEM_FORMAT_VERSION))throw new PmCliError(`Stored item uses format version ${formatVersion}; this runtime supports up to ${CURRENT_ITEM_FORMAT_VERSION}. Upgrade pm before reading or changing this item.`,EXIT_CODE.CONFLICT,{code:"item_format_version_unsupported",format_version:formatVersion,required:"Upgrade to a pm runtime supporting the stored item format.",nextSteps:["Preserve the original item and history; do not lower pm_format_version to bypass compatibility checks."]})}function buildKnownItemMetadataKeys(runtimeContext){const knownKeys=new Set(STATIC_ITEM_METADATA_FIELD_SET);for(const definition of runtimeContext.fieldRegistry?.definitions??[])knownKeys.add(definition.metadata_key);for(const fieldName of runtimeContext.extensionFieldNames)knownKeys.add(fieldName);return knownKeys}function assertItemMetadataCondition(condition,message){condition||validationError(message)}function requireItemMetadataRecord(value,message){return(typeof value!="object"||value===null||Array.isArray(value))&&validationError(message),value}function assertTimestampField(record,fieldName){const rawValue=record[fieldName];assertItemMetadataCondition(typeof rawValue=="string",`${fieldName} must be a string`),assertItemMetadataCondition(isTimestampLiteral(rawValue),`${fieldName} must be a valid ISO timestamp`)}function assertPositiveIntegerField(record,fieldName,messagePrefix){const value=record[fieldName];value!==void 0&&assertItemMetadataCondition(typeof value=="number"&&Number.isInteger(value)&&value>=1,`${messagePrefix} must be an integer >= 1`)}function assertOptionalTimestampString(record,fieldName,messagePrefix){const value=record[fieldName];value!==void 0&&(assertItemMetadataCondition(typeof value=="string",`${messagePrefix} must be a string`),assertItemMetadataCondition(isTimestampLiteral(value),`${messagePrefix} must be a valid ISO timestamp`))}function assertRecurrenceWeekdays(value){if(value!==void 0){assertItemMetadataCondition(Array.isArray(value),"event.recurrence.by_weekday must be an array");for(const weekday of value){assertItemMetadataCondition(typeof weekday=="string","event.recurrence.by_weekday entries must be strings");const normalizedWeekday=weekday.trim().toLowerCase();assertItemMetadataCondition(RECURRENCE_WEEKDAY_VALUES.includes(normalizedWeekday),`event.recurrence.by_weekday entries must be one of: ${RECURRENCE_WEEKDAY_VALUES.join(", ")}`)}}}function assertRecurrenceMonthDays(value){if(value!==void 0){assertItemMetadataCondition(Array.isArray(value),"event.recurrence.by_month_day must be an array");for(const day of value)assertItemMetadataCondition(typeof day=="number"&&Number.isInteger(day)&&day>=1&&day<=31,"event.recurrence.by_month_day entries must be integers 1..31")}}function assertRecurrenceExdates(value){if(value!==void 0){assertItemMetadataCondition(Array.isArray(value),"event.recurrence.exdates must be an array");for(const exdate of value)assertItemMetadataCondition(typeof exdate=="string","event.recurrence.exdates entries must be strings"),assertItemMetadataCondition(isTimestampLiteral(exdate),"event.recurrence.exdates entries must be valid ISO timestamps")}}function assertValidRecurrenceRule(recurrence){const recurrenceRecord=requireItemMetadataRecord(recurrence,"event.recurrence must be an object");assertItemMetadataCondition(typeof recurrenceRecord.freq=="string","event.recurrence.freq must be a string");const frequency=recurrenceRecord.freq.trim().toLowerCase();assertItemMetadataCondition(RECURRENCE_FREQUENCY_VALUES.includes(frequency),`event.recurrence.freq must be one of: ${RECURRENCE_FREQUENCY_VALUES.join(", ")}`),assertPositiveIntegerField(recurrenceRecord,"interval","event.recurrence.interval"),assertPositiveIntegerField(recurrenceRecord,"count","event.recurrence.count"),assertOptionalTimestampString(recurrenceRecord,"until","event.recurrence.until"),assertRecurrenceWeekdays(recurrenceRecord.by_weekday),assertRecurrenceMonthDays(recurrenceRecord.by_month_day),assertRecurrenceExdates(recurrenceRecord.exdates)}function assertRequiredItemMetadataFields(record){for(const fieldName of REQUIRED_STRING_FIELDS)assertItemMetadataCondition(typeof record[fieldName]=="string",`${fieldName} is required and must be a string`);const itemType=record.type;assertItemMetadataCondition(typeof itemType=="string"&&itemType.trim().length>0,"type must be a non-empty string");const formatVersion=record.pm_format_version;return formatVersion!==void 0&&assertItemMetadataCondition(typeof formatVersion=="number"&&Number.isInteger(formatVersion)&&formatVersion>=BASELINE_ITEM_FORMAT_VERSION,`pm_format_version must be an integer >= ${BASELINE_ITEM_FORMAT_VERSION}`),itemType}function assertStatusItemMetadataField(record,runtimeContext){const status=record.status;assertItemMetadataCondition(typeof status=="string"&&status.trim().length>0,"status must be a non-empty string");const statusRegistry=runtimeContext?.statusRegistry,normalizedStatus=normalizeStatusInput(status,statusRegistry),statusDomain=statusRegistry?statusRegistry.definitions.map(definition=>definition.id):[...STATUS_VALUES];assertItemMetadataCondition(normalizedStatus!==void 0,`status must be one of: ${statusDomain.join(", ")}`)}function assertPriorityAndTags(record){const priority=record.priority;assertItemMetadataCondition(typeof priority=="number"&&Number.isInteger(priority)&&[0,1,2,3,4].includes(priority),"priority must be an integer 0..4");const tags=record.tags;assertItemMetadataCondition(Array.isArray(tags),"tags must be an array");for(const tag of tags)assertItemMetadataCondition(typeof tag=="string","tags entries must be strings")}function assertConfidenceItemMetadataField(record){const confidence=record.confidence;if(confidence!==void 0){if(typeof confidence=="number"){assertItemMetadataCondition(Number.isInteger(confidence)&&confidence>=0&&confidence<=100,"confidence number value must be an integer 0..100");return}if(typeof confidence=="string"){const normalizedConfidence=confidence.trim().toLowerCase(),isKnownTextConfidence=normalizedConfidence==="med"||CONFIDENCE_TEXT_VALUES.includes(normalizedConfidence);assertItemMetadataCondition(isKnownTextConfidence,`confidence string value must be one of: ${[...CONFIDENCE_TEXT_VALUES,"med"].join(", ")}`);return}assertItemMetadataCondition(!1,"confidence must be a number or string")}}function assertSeverityItemMetadataField(record){const severity=record.severity;if(severity===void 0)return;typeof severity!="string"&&validationError("severity must be a string");const normalizedSeverity=severity.trim().toLowerCase(),isKnownSeverity=normalizedSeverity==="med"||ISSUE_SEVERITY_VALUES.includes(normalizedSeverity);assertItemMetadataCondition(isKnownSeverity,`severity value must be one of: ${[...ISSUE_SEVERITY_VALUES,"med"].join(", ")}`)}function assertRegressionItemMetadataField(record){record.regression!==void 0&&typeof record.regression!="boolean"&&validationError("regression must be a boolean")}function assertReminderEntries(record){const reminders=record.reminders;if(reminders!==void 0){assertItemMetadataCondition(Array.isArray(reminders),"reminders must be an array");for(const reminder of reminders){const reminderRecord=requireItemMetadataRecord(reminder,"reminders entries must be objects");assertItemMetadataCondition(typeof reminderRecord.at=="string","reminder.at must be a string"),assertItemMetadataCondition(isTimestampLiteral(reminderRecord.at),"reminder.at must be a valid ISO timestamp"),assertItemMetadataCondition(typeof reminderRecord.text=="string","reminder.text must be a string"),assertItemMetadataCondition(reminderRecord.text.trim().length>0,"reminder.text must not be empty")}}}function assertEventStringFields(eventRecord){for(const stringField of["title","description","location","timezone"])eventRecord[stringField]!==void 0&&(assertItemMetadataCondition(typeof eventRecord[stringField]=="string",`event.${stringField} must be a string`),assertItemMetadataCondition(eventRecord[stringField].trim().length>0,`event.${stringField} must not be empty`))}function assertEventRecurrence(eventRecord){eventRecord.recurrence!==void 0&&(assertValidRecurrenceRule(eventRecord.recurrence),eventRecord.recurrence.until!==void 0&&assertItemMetadataCondition(compareTimestampStrings(eventRecord.recurrence.until,eventRecord.start_at)>=0,"event.recurrence.until must be at or after event.start_at"))}function assertCalendarEventEntry(event){const eventRecord=requireItemMetadataRecord(event,"events entries must be objects");assertItemMetadataCondition(typeof eventRecord.start_at=="string","event.start_at must be a string"),assertItemMetadataCondition(isTimestampLiteral(eventRecord.start_at),"event.start_at must be a valid ISO timestamp"),eventRecord.end_at!==void 0&&(assertItemMetadataCondition(typeof eventRecord.end_at=="string","event.end_at must be a string"),assertItemMetadataCondition(isTimestampLiteral(eventRecord.end_at),"event.end_at must be a valid ISO timestamp"),assertItemMetadataCondition(compareTimestampStrings(eventRecord.end_at,eventRecord.start_at)>0,"event.end_at must be after event.start_at")),assertEventStringFields(eventRecord),eventRecord.all_day!==void 0&&assertItemMetadataCondition(typeof eventRecord.all_day=="boolean","event.all_day must be a boolean"),assertEventRecurrence(eventRecord)}function assertCalendarEvents(record){const events=record.events;if(events!==void 0){assertItemMetadataCondition(Array.isArray(events),"events must be an array");for(const event of events)assertCalendarEventEntry(event)}}function assertOptionalStringFields(record){for(const fieldName of["source_type","source_owner","design","external_ref"]){const value=record[fieldName];value!==void 0&&assertItemMetadataCondition(typeof value=="string",`${fieldName} must be a string`)}}function assertTypeOptionsField(record){const typeOptions=record.type_options;if(typeOptions===void 0)return;const typeOptionsRecord=requireItemMetadataRecord(typeOptions,"type_options must be an object");for(const[optionKey,optionValue]of Object.entries(typeOptionsRecord))assertItemMetadataCondition(optionKey.trim().length>0,"type_options keys must be non-empty"),assertItemMetadataCondition(typeof optionValue=="string","type_options values must be strings"),assertItemMetadataCondition(optionValue.trim().length>0,"type_options values must be non-empty strings")}function coerceRuntimeItemMetadataFields(record,itemType,runtimeContext){if(runtimeContext?.fieldRegistry)for(const definition of runtimeContext.fieldRegistry.definitions){const fieldValue=record[definition.metadata_key];if(fieldValue===void 0){runtimeFieldRequiredForType(definition,itemType)&&validationError(`missing required schema field: ${definition.metadata_key}`);continue}try{record[definition.metadata_key]=coerceRuntimeFieldValue(definition,fieldValue,`metadata field "${definition.metadata_key}"`,"metadata")}catch(error){validationError(String(error?.message).replace(/^Invalid\s+/u,""))}}}function assertRuntimeUnknownItemMetadataFields(record,runtimeContext){if(!runtimeContext||runtimeContext.unknownFieldPolicy==="allow")return;const knownKeys=buildKnownItemMetadataKeys(runtimeContext),unknownKeys=Object.keys(record).filter(key=>!knownKeys.has(key)).sort((left,right)=>left.localeCompare(right));unknownKeys.length!==0&&(runtimeContext.unknownFieldPolicy==="reject"?validationError(`unknown schema fields are not allowed: ${unknownKeys.join(", ")}`):runtimeContext.onWarning?.(`item_unknown_schema_fields:${unknownKeys.join(",")}`))}function assertValidItemMetadata(itemMetadata,runtimeContext){const record=requireItemMetadataRecord(itemMetadata,"item metadata must be an object"),itemType=assertRequiredItemMetadataFields(record);assertStatusItemMetadataField(record,runtimeContext),assertPriorityAndTags(record),assertConfidenceItemMetadataField(record),assertSeverityItemMetadataField(record),assertRegressionItemMetadataField(record),assertTimestampField(record,"created_at"),assertTimestampField(record,"updated_at"),record.deadline!==void 0&&assertTimestampField(record,"deadline"),assertReminderEntries(record),assertCalendarEvents(record),assertOptionalTimestampString(record,"closed_at","closed_at"),assertOptionalTimestampString(record,"completed_at","completed_at"),assertOptionalStringFields(record),assertTypeOptionsField(record),coerceRuntimeItemMetadataFields(record,itemType,runtimeContext),assertRuntimeUnknownItemMetadataFields(record,runtimeContext)}function sortDependencies(values){if(!(!values||values.length===0))return[...values].map(value=>({id:value.id.trim(),kind:value.kind,created_at:value.created_at,author:value.author?.trim()||void 0,source_kind:value.source_kind?.trim()||void 0,author_source:value.author_source})).sort((a,b)=>{const byCreated=compareTimestampStrings(a.created_at,b.created_at);if(byCreated!==0)return byCreated;const byId=a.id.localeCompare(b.id);if(byId!==0)return byId;const byKind=a.kind.localeCompare(b.kind);return byKind!==0?byKind:(a.source_kind??"").localeCompare(b.source_kind??"")})}function sortLogValues(values){if(!(!values||values.length===0))return[...values].sort((a,b)=>{const byCreated=compareTimestampStrings(a.created_at,b.created_at);if(byCreated!==0)return byCreated;const byText=a.text.localeCompare(b.text);return byText!==0?byText:a.author.localeCompare(b.author)})}function sortReminders(values){if(!values||values.length===0)return;const normalized=[...values].map(value=>({at:value.at,text:value.text.trim()})).filter(value=>value.text.length>0).sort((a,b)=>{const byAt=compareTimestampStrings(a.at,b.at);return byAt!==0?byAt:a.text.localeCompare(b.text)});return normalized.length===0?void 0:normalized}function normalizeRecurrenceRule(value){if(!value)return;const normalizedFrequency=value.freq.trim().toLowerCase();if(!RECURRENCE_FREQUENCY_VALUES.includes(normalizedFrequency))return;const byWeekday=Array.from(new Set((value.by_weekday??[]).map(weekday=>weekday.trim().toLowerCase()).filter(weekday=>RECURRENCE_WEEKDAY_VALUES.includes(weekday)))).sort((a,b)=>weekdayOrderIndex(a)-weekdayOrderIndex(b)),byMonthDay=Array.from(new Set((value.by_month_day??[]).filter(day=>Number.isInteger(day)&&day>=1&&day<=31).map(day=>day))).sort((a,b)=>a-b),exdates=Array.from(new Set((value.exdates??[]).map(timestamp=>timestamp.trim()).filter(timestamp=>isTimestampLiteral(timestamp)))).sort((a,b)=>compareTimestampStrings(a,b)),normalized={freq:normalizedFrequency,interval:value.interval!==void 0&&value.interval>1?value.interval:void 0,count:value.count,until:value.until?.trim()||void 0,by_weekday:byWeekday.length>0?byWeekday:void 0,by_month_day:byMonthDay.length>0?byMonthDay:void 0,exdates:exdates.length>0?exdates:void 0};for(const[key,fieldValue]of Object.entries(normalized))fieldValue===void 0&&delete normalized[key];return normalized}function sortEvents(values){return!Array.isArray(values)||values.length===0?void 0:[...values].map(normalizeCalendarEvent).sort(compareCalendarEvents)}function normalizeCalendarEvent(value){const event={start_at:value.start_at,end_at:value.end_at||void 0,title:value.title?.trim()||void 0,description:value.description?.trim()||void 0,location:value.location?.trim()||void 0,all_day:value.all_day,timezone:value.timezone?.trim()||void 0,recurrence:normalizeRecurrenceRule(value.recurrence)};return deleteUndefinedFields(event),event}function compareCalendarEvents(a,b){return firstNonZeroComparison([compareTimestampStrings(a.start_at,b.start_at),(a.end_at??"").localeCompare(b.end_at??""),(a.title??"").localeCompare(b.title??""),+!!a.all_day-+!!b.all_day,(a.timezone??"").localeCompare(b.timezone??""),(a.location??"").localeCompare(b.location??""),(a.description??"").localeCompare(b.description??""),JSON.stringify(a.recurrence??{}).localeCompare(JSON.stringify(b.recurrence??{}))])}function normalizeFiles(values){if(!(!values||values.length===0))return values.map(value=>({path:normalizePathValue(value.path),scope:value.scope,note:value.note?.trim()||void 0}))}function normalizeTestRunSummaries(values){if(!values||values.length===0)return;const normalized=values.map(normalizeTestRunSummary).filter(value=>value.run_id.length>0&&value.started_at.length>0&&value.finished_at.length>0&&value.recorded_at.length>0).sort((a,b)=>firstNonZeroComparison([compareTimestampStrings(a.recorded_at,b.recorded_at),a.run_id.localeCompare(b.run_id),a.kind.localeCompare(b.kind)]));return normalized.length>0?normalized:void 0}function normalizeNonNegativeInteger(value){return typeof value=="number"&&Number.isFinite(value)&&value>=0?Math.floor(value):void 0}function normalizePositiveInteger(value){return typeof value=="number"&&Number.isFinite(value)&&value>=1?Math.floor(value):void 0}function stringOrEmpty(value){return typeof value=="string"?value:""}function normalizeTestRunMeasurements(value){if(!Array.isArray(value))return;const normalized=value.filter(measurement=>measurement!==null&&typeof measurement=="object"&&typeof measurement.name=="string"&&measurement.name.trim().length>0&&typeof measurement.value=="number"&&Number.isFinite(measurement.value)&&typeof measurement.recorded_at=="string"&&measurement.recorded_at.trim().length>0).map(measurement=>({name:measurement.name.trim(),value:measurement.value,unit:typeof measurement.unit=="string"&&measurement.unit.trim()||void 0,threshold:typeof measurement.threshold=="number"&&Number.isFinite(measurement.threshold)?measurement.threshold:void 0,recorded_at:measurement.recorded_at.trim()})),deduplicated=[...new Map(normalized.map(measurement=>[measurement.name,measurement])).values()].sort((left,right)=>left.name.localeCompare(right.name)).slice(0,32);return deduplicated.length>0?deduplicated:void 0}function normalizeTestRunEnum(value,allowedValues){return typeof value=="string"&&allowedValues.has(value)?value:void 0}function normalizeTestRunExecutions(values){if(!Array.isArray(values))return;const executions=values.filter(execution=>execution&&typeof execution.command=="string"&&execution.command.trim().length>0).slice(0,32).map(execution=>({command:execution.command.trim(),requested_pm_context_mode:normalizeTestRunEnum(execution.requested_pm_context_mode,LINKED_TEST_PM_CONTEXT_MODE_VALUES),pm_context_mode:normalizeTestRunEnum(execution.pm_context_mode,LINKED_TEST_PM_CONTEXT_MODE_VALUES),workspace_context_mode:normalizeTestRunEnum(execution.workspace_context_mode,LINKED_TEST_WORKSPACE_CONTEXT_MODE_VALUES),trust_reason:normalizeTestRunEnum(execution.trust_reason,LINKED_TEST_TRUST_REASON_VALUES)}));return executions.length>0?executions:void 0}function normalizeTestRunSummary(value){const runId=typeof value.run_id=="string"?value.run_id.trim():"",kind=value.kind==="test"||value.kind==="test-all"?value.kind:"test",status=ITEM_TEST_RUN_STATUS_VALUES.has(value.status)?value.status:"failed",summary={run_id:runId,kind,status,started_at:stringOrEmpty(value.started_at),finished_at:stringOrEmpty(value.finished_at),recorded_at:stringOrEmpty(value.recorded_at),attempt:normalizePositiveInteger(value.attempt),resumed_from:value.resumed_from?.trim()||void 0,passed:normalizeNonNegativeInteger(value.passed)??0,failed:normalizeNonNegativeInteger(value.failed)??0,skipped:normalizeNonNegativeInteger(value.skipped)??0,items:normalizeNonNegativeInteger(value.items),linked_tests:normalizeNonNegativeInteger(value.linked_tests),fail_on_skipped_triggered:value.fail_on_skipped_triggered===!0?!0:void 0,measurements:normalizeTestRunMeasurements(value.measurements),executions:normalizeTestRunExecutions(value.executions)};return deleteUndefinedFields(summary),summary}function sortTests(values){if(!(!Array.isArray(values)||values.length===0))return values.map(normalizeLinkedTest)}function normalizeTrimmedStringList(value){if(!Array.isArray(value))return;const normalized=[...new Set(value.filter(entry=>typeof entry=="string").map(entry=>entry.trim()).filter(entry=>entry.length>0))].sort((a,b)=>a.localeCompare(b));return normalized.length>0?normalized:void 0}function isPlainObjectRecord(value){if(!value||typeof value!="object"||Array.isArray(value))return!1;const prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function isUnsafeObjectKey(key){return key==="__proto__"||key==="constructor"||key==="prototype"}function normalizeStringRecord(value){if(!isPlainObjectRecord(value))return;const entries=Object.entries(value).map(([key,recordValue])=>[key.trim(),String(recordValue).trim()]).filter(([key,recordValue])=>key.length>0&&!isUnsafeObjectKey(key)&&recordValue.length>0).sort(([left],[right])=>left.localeCompare(right));return entries.length>0?Object.fromEntries(entries):void 0}function normalizeNumericRecord(value){if(!isPlainObjectRecord(value))return;const entries=Object.entries(value).map(([key,recordValue])=>[key.trim(),Number(recordValue)]).filter(([key,recordValue])=>key.length>0&&!isUnsafeObjectKey(key)&&Number.isFinite(recordValue)).sort(([left],[right])=>left.localeCompare(right));return entries.length>0?Object.fromEntries(entries):void 0}function normalizeLinkedTestContextMode(value){const normalized=value?.trim().toLowerCase();if(!(!normalized||!LINKED_TEST_PM_CONTEXT_MODE_VALUES.has(normalized)))return normalized}function normalizeLinkedTestWorkspaceContextMode(value){const normalized=value?.trim().toLowerCase();if(!(!normalized||!LINKED_TEST_WORKSPACE_CONTEXT_MODE_VALUES.has(normalized)))return normalized}function normalizeLinkedTestProvenance(value,invalid){if(invalid===!0)return{provenance_invalid:!0};if(value===void 0)return{};if(!isPlainObjectRecord(value))return{provenance_invalid:!0};const author=trimStringOrUndefined(value.author),createdAt=trimStringOrUndefined(value.created_at),sourceKind=value.source_kind;return!author||!createdAt||!isTimestampLiteral(createdAt)||sourceKind!=="local_mutation"&&sourceKind!=="merge_union"?{provenance_invalid:!0}:{provenance:{author,created_at:createdAt,source_kind:sourceKind,source_ref:trimStringOrUndefined(value.source_ref)}}}function normalizeLinkedTest(value){const test={command:value.command?.trim()||void 0,path:value.path?normalizePathValue(value.path):void 0,scope:value.scope,timeout_seconds:typeof value.timeout_seconds=="number"&&Number.isFinite(value.timeout_seconds)&&value.timeout_seconds>0?value.timeout_seconds:void 0,pm_context_mode:normalizeLinkedTestContextMode(value.pm_context_mode),workspace_context_mode:normalizeLinkedTestWorkspaceContextMode(value.workspace_context_mode),...normalizeLinkedTestProvenance(value.provenance,value.provenance_invalid),updated_by:trimStringOrUndefined(value.updated_by),updated_at:trimStringOrUndefined(value.updated_at),env_set:normalizeStringRecord(value.env_set),env_clear:normalizeTrimmedStringList(value.env_clear),shared_host_safe:value.shared_host_safe===!0?!0:void 0,assert_stdout_contains:normalizeTrimmedStringList(value.assert_stdout_contains),assert_stdout_regex:normalizeTrimmedStringList(value.assert_stdout_regex),assert_stderr_contains:normalizeTrimmedStringList(value.assert_stderr_contains),assert_stderr_regex:normalizeTrimmedStringList(value.assert_stderr_regex),assert_stdout_min_lines:normalizeNonNegativeInteger(value.assert_stdout_min_lines),assert_json_field_equals:normalizeStringRecord(value.assert_json_field_equals),assert_json_field_gte:normalizeNumericRecord(value.assert_json_field_gte),note:value.note?.trim()||void 0};return deleteUndefinedFields(test),test}function sortDocs(values){if(!(!values||values.length===0))return[...values].map(value=>({path:normalizePathValue(value.path),scope:value.scope,note:value.note?.trim()||void 0})).sort((a,b)=>{const byScope=a.scope.localeCompare(b.scope);if(byScope!==0)return byScope;const byPath=a.path.localeCompare(b.path);return byPath!==0?byPath:(a.note??"").localeCompare(b.note??"")})}function trimStringOrUndefined(value){if(typeof value!="string")return;const trimmed=value.trim();return trimmed.length>0?trimmed:void 0}function normalizePlanStepLinks(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,id=trimStringOrUndefined(record.id),kind=trimStringOrUndefined(record.kind);if(!id||!kind)continue;const link={id,kind},note=trimStringOrUndefined(record.note);note&&(link.note=note),record.required_before_step===!0&&(link.required_before_step=!0),out.push(link)}return out.length>0?out:void 0}function normalizePlanStepFiles(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,path=trimStringOrUndefined(record.path);if(!path)continue;const file={path:normalizePathValue(path)};(record.scope==="project"||record.scope==="global")&&(file.scope=record.scope);const note=trimStringOrUndefined(record.note);note&&(file.note=note),out.push(file)}return out.length>0?out:void 0}function normalizePlanStepTests(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,command=trimStringOrUndefined(record.command),path=trimStringOrUndefined(record.path);if(!command&&!path)continue;const test={};command&&(test.command=command),path&&(test.path=normalizePathValue(path));const note=trimStringOrUndefined(record.note);note&&(test.note=note),out.push(test)}return out.length>0?out:void 0}function normalizePlanStepDocs(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,path=trimStringOrUndefined(record.path);if(!path)continue;const doc={path:normalizePathValue(path)};(record.scope==="project"||record.scope==="global")&&(doc.scope=record.scope);const note=trimStringOrUndefined(record.note);note&&(doc.note=note),out.push(doc)}return out.length>0?out:void 0}function normalizePlanStepEntry(entry){if(entry===null||typeof entry!="object")return;const record=entry,id=trimStringOrUndefined(record.id),title=trimStringOrUndefined(record.title),statusRaw=trimStringOrUndefined(record.status),status=statusRaw&&PLAN_STEP_STATUS_SET.has(statusRaw)?statusRaw:void 0,order=coerceFiniteNumber(record.order)??Number.NaN,created_at=typeof record.created_at=="string"?record.created_at:"",updated_at=typeof record.updated_at=="string"?record.updated_at:"";if(!id||!title||!status||!Number.isFinite(order)||!created_at||!updated_at)return;const step={id,order,title,status,created_at,updated_at};return applyPlanStepOptionalFields(step,record),step}function applyPlanStepOptionalFields(step,record){const stringFields=[["body","body"],["owner","owner"],["evidence","evidence"],["blocked_reason","blocked_reason"],["superseded_by","superseded_by"]];for(const[target,source]of stringFields){const value=trimStringOrUndefined(record[source]);value&&(step[target]=value)}const completedAt=typeof record.completed_at=="string"?record.completed_at:void 0;completedAt&&completedAt.length>0&&(step.completed_at=completedAt);const collectionFields=[["linked_items","linked_items",normalizePlanStepLinks],["files","files",normalizePlanStepFiles],["tests","tests",normalizePlanStepTests],["docs","docs",normalizePlanStepDocs]];for(const[target,source,normalize]of collectionFields){const value=normalize(record[source]);value&&(step[target]=value)}}function normalizePlanSteps(value){if(!Array.isArray(value))return;const out=value.flatMap(entry=>{const step=normalizePlanStepEntry(entry);return step?[step]:[]});return out.sort((left,right)=>left.order-right.order),out.length>0?out:void 0}function normalizePlanDecisions(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,ts=typeof record.ts=="string"?record.ts:"",author=typeof record.author=="string"?record.author:"",decision=trimStringOrUndefined(record.decision);if(!ts||!author||!decision)continue;const item={ts,author,decision},rationale=trimStringOrUndefined(record.rationale);rationale&&(item.rationale=rationale);const evidence=trimStringOrUndefined(record.evidence);evidence&&(item.evidence=evidence);const stepId=trimStringOrUndefined(record.step_id);stepId&&(item.step_id=stepId),out.push(item)}return out.length>0?out:void 0}function normalizePlanDiscoveries(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,ts=typeof record.ts=="string"?record.ts:"",author=typeof record.author=="string"?record.author:"",text=trimStringOrUndefined(record.text);if(!ts||!author||!text)continue;const item={ts,author,text},stepId=trimStringOrUndefined(record.step_id);stepId&&(item.step_id=stepId),out.push(item)}return out.length>0?out:void 0}function normalizePlanValidation(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,text=trimStringOrUndefined(record.text);if(!text)continue;const item={text},command=trimStringOrUndefined(record.command);command&&(item.command=command);const expected=trimStringOrUndefined(record.expected);expected&&(item.expected=expected),out.push(item)}return out.length>0?out:void 0}function normalizeTypeOptions(values){if(!values)return;const normalizedEntries=Object.entries(values).map(([key,value])=>[key.trim(),value.trim()]).filter(([key,value])=>key.length>0&&value.length>0).sort((left,right)=>left[0].localeCompare(right[0]));if(normalizedEntries.length!==0)return Object.fromEntries(normalizedEntries)}function normalizeBody(body){let start=0;for(;start<body.length&&body[start]===`
|
|
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]="2789e87f-0706-52e8-8f4c-3855c65c618c")}catch{}})();import{encode as encodeToon}from"@toon-format/toon";import{isDeepStrictEqual}from"node:util";import{CONFIDENCE_TEXT_VALUES,ISSUE_SEVERITY_VALUES,PLAN_STEP_STATUS_VALUES,RECURRENCE_FREQUENCY_VALUES,RECURRENCE_WEEKDAY_VALUES,STATUS_VALUES,weekdayOrderIndex}from"../../types/index.js";import{coerceRuntimeFieldValue}from"../schema/runtime-field-values.js";import{resolveRuntimeFieldRegistry,resolveRuntimeStatusRegistry}from"../schema/runtime-schema.js";import{BASELINE_ITEM_FORMAT_VERSION,CURRENT_ITEM_FORMAT_VERSION,effectiveItemFormatVersion,normalizeItemFormatVersion}from"./item-format-version.js";import{normalizeStatusInput}from"./status.js";import{decodeToonItemContent}from"./toon-decode.js";import{EXIT_CODE,ITEM_METADATA_KEY_ORDER}from"../shared/constants.js";import{findFirstMergeConflictMarker}from"../shared/conflict-markers.js";import{PmCliError}from"../shared/errors.js";import{orderObject}from"../shared/serialization.js";import{compareTimestampStrings,isRfc3339DateTime,isTimestampLiteral}from"../shared/time.js";import{coerceFiniteNumber}from"../shared/primitives.js";const LINKED_TEST_PM_CONTEXT_MODE_VALUES=new Set(["schema","tracker","auto","none"]),LINKED_TEST_WORKSPACE_CONTEXT_MODE_VALUES=new Set(["source","isolated","snapshot"]),LINKED_TEST_TRUST_REASON_VALUES=new Set(["legacy","local_mutation","local_source_ref","acknowledged","invalid_provenance","foreign_source_ref"]),ITEM_TEST_RUN_STATUS_VALUES=new Set(["passed","failed","stopped","canceled"]),PLAN_STEP_STATUS_SET=new Set(PLAN_STEP_STATUS_VALUES);function normalizePathValue(value){return value.replaceAll("\\","/")}function firstNonZeroComparison(comparisons){for(const comparison of comparisons)if(comparison!==0)return comparison;return 0}function deleteUndefinedFields(record){for(const[key,value]of Object.entries(record))value===void 0&&delete record[key]}const REQUIRED_STRING_FIELDS=["id","title","description","created_at","updated_at"],STATIC_ITEM_METADATA_FIELD_SET=new Set(ITEM_METADATA_KEY_ORDER);function resolveRuntimeSchemaValidationContext(options){if(options?.schema)return{statusRegistry:resolveRuntimeStatusRegistry(options.schema),fieldRegistry:resolveRuntimeFieldRegistry(options.schema),unknownFieldPolicy:options.schema.unknown_field_policy??"allow",extensionFieldNames:new Set(options.extensionFieldNames??[]),onWarning:options.onWarning}}function runtimeFieldRequiredForType(definition,typeName){return definition.required?definition.required_types.length===0?!0:definition.required_types.map(value=>value.toLowerCase()).includes(typeName.trim().toLowerCase()):!1}function validationError(message){const field=message.match(/^([a-z_][\w.]*)\s/u)?.[1];throw new PmCliError(`Invalid item metadata: ${message}`,EXIT_CODE.GENERIC_FAILURE,{code:"item_document_invalid",reason:message.includes("required")?"missing_required_field":"schema_validation_error",...field?{field}:{},required:"Provide an item document whose metadata satisfies the active runtime schema.",why:message})}function documentSyntaxError(format,message){throw new PmCliError(message,EXIT_CODE.GENERIC_FAILURE,{code:"item_document_invalid",reason:"syntax_error",format,required:`Provide a syntactically valid ${format==="toon"?"TOON":"JSON Markdown"} item document.`,why:"The document could not be decoded far enough to validate item metadata."})}function assertSupportedItemFormat(metadata,required){if(!required||typeof metadata!="object"||metadata===null)return;const formatVersion=effectiveItemFormatVersion(metadata);if(!(formatVersion<=CURRENT_ITEM_FORMAT_VERSION))throw new PmCliError(`Stored item uses format version ${formatVersion}; this runtime supports up to ${CURRENT_ITEM_FORMAT_VERSION}. Upgrade pm before reading or changing this item.`,EXIT_CODE.CONFLICT,{code:"item_format_version_unsupported",format_version:formatVersion,required:"Upgrade to a pm runtime supporting the stored item format.",nextSteps:["Preserve the original item and history; do not lower pm_format_version to bypass compatibility checks."]})}function buildKnownItemMetadataKeys(runtimeContext){const knownKeys=new Set(STATIC_ITEM_METADATA_FIELD_SET);for(const definition of runtimeContext.fieldRegistry?.definitions??[])knownKeys.add(definition.metadata_key);for(const fieldName of runtimeContext.extensionFieldNames)knownKeys.add(fieldName);return knownKeys}function assertItemMetadataCondition(condition,message){condition||validationError(message)}function requireItemMetadataRecord(value,message){return(typeof value!="object"||value===null||Array.isArray(value))&&validationError(message),value}function assertTimestampField(record,fieldName){const rawValue=record[fieldName];assertItemMetadataCondition(typeof rawValue=="string",`${fieldName} must be a string`),assertItemMetadataCondition(isTimestampLiteral(rawValue),`${fieldName} must be a valid ISO timestamp`)}function assertPositiveIntegerField(record,fieldName,messagePrefix){const value=record[fieldName];value!==void 0&&assertItemMetadataCondition(typeof value=="number"&&Number.isInteger(value)&&value>=1,`${messagePrefix} must be an integer >= 1`)}function assertOptionalTimestampString(record,fieldName,messagePrefix){const value=record[fieldName];value!==void 0&&(assertItemMetadataCondition(typeof value=="string",`${messagePrefix} must be a string`),assertItemMetadataCondition(isTimestampLiteral(value),`${messagePrefix} must be a valid ISO timestamp`))}function assertRecurrenceWeekdays(value){if(value!==void 0){assertItemMetadataCondition(Array.isArray(value),"event.recurrence.by_weekday must be an array");for(const weekday of value){assertItemMetadataCondition(typeof weekday=="string","event.recurrence.by_weekday entries must be strings");const normalizedWeekday=weekday.trim().toLowerCase();assertItemMetadataCondition(RECURRENCE_WEEKDAY_VALUES.includes(normalizedWeekday),`event.recurrence.by_weekday entries must be one of: ${RECURRENCE_WEEKDAY_VALUES.join(", ")}`)}}}function assertRecurrenceMonthDays(value){if(value!==void 0){assertItemMetadataCondition(Array.isArray(value),"event.recurrence.by_month_day must be an array");for(const day of value)assertItemMetadataCondition(typeof day=="number"&&Number.isInteger(day)&&day>=1&&day<=31,"event.recurrence.by_month_day entries must be integers 1..31")}}function assertRecurrenceExdates(value){if(value!==void 0){assertItemMetadataCondition(Array.isArray(value),"event.recurrence.exdates must be an array");for(const exdate of value)assertItemMetadataCondition(typeof exdate=="string","event.recurrence.exdates entries must be strings"),assertItemMetadataCondition(isTimestampLiteral(exdate),"event.recurrence.exdates entries must be valid ISO timestamps")}}function assertValidRecurrenceRule(recurrence){const recurrenceRecord=requireItemMetadataRecord(recurrence,"event.recurrence must be an object");assertItemMetadataCondition(typeof recurrenceRecord.freq=="string","event.recurrence.freq must be a string");const frequency=recurrenceRecord.freq.trim().toLowerCase();assertItemMetadataCondition(RECURRENCE_FREQUENCY_VALUES.includes(frequency),`event.recurrence.freq must be one of: ${RECURRENCE_FREQUENCY_VALUES.join(", ")}`),assertPositiveIntegerField(recurrenceRecord,"interval","event.recurrence.interval"),assertPositiveIntegerField(recurrenceRecord,"count","event.recurrence.count"),assertOptionalTimestampString(recurrenceRecord,"until","event.recurrence.until"),assertRecurrenceWeekdays(recurrenceRecord.by_weekday),assertRecurrenceMonthDays(recurrenceRecord.by_month_day),assertRecurrenceExdates(recurrenceRecord.exdates)}function assertRequiredItemMetadataFields(record){for(const fieldName of REQUIRED_STRING_FIELDS)assertItemMetadataCondition(typeof record[fieldName]=="string",`${fieldName} is required and must be a string`);const itemType=record.type;assertItemMetadataCondition(typeof itemType=="string"&&itemType.trim().length>0,"type must be a non-empty string");const formatVersion=record.pm_format_version;return formatVersion!==void 0&&assertItemMetadataCondition(typeof formatVersion=="number"&&Number.isInteger(formatVersion)&&formatVersion>=BASELINE_ITEM_FORMAT_VERSION,`pm_format_version must be an integer >= ${BASELINE_ITEM_FORMAT_VERSION}`),itemType}function assertStatusItemMetadataField(record,runtimeContext){const status=record.status;assertItemMetadataCondition(typeof status=="string"&&status.trim().length>0,"status must be a non-empty string");const statusRegistry=runtimeContext?.statusRegistry,normalizedStatus=normalizeStatusInput(status,statusRegistry),statusDomain=statusRegistry?statusRegistry.definitions.map(definition=>definition.id):[...STATUS_VALUES];assertItemMetadataCondition(normalizedStatus!==void 0,`status must be one of: ${statusDomain.join(", ")}`)}function assertPriorityAndTags(record){const priority=record.priority;assertItemMetadataCondition(typeof priority=="number"&&Number.isInteger(priority)&&[0,1,2,3,4].includes(priority),"priority must be an integer 0..4");const tags=record.tags;assertItemMetadataCondition(Array.isArray(tags),"tags must be an array");for(const tag of tags)assertItemMetadataCondition(typeof tag=="string","tags entries must be strings")}function assertConfidenceItemMetadataField(record){const confidence=record.confidence;if(confidence!==void 0){if(typeof confidence=="number"){assertItemMetadataCondition(Number.isInteger(confidence)&&confidence>=0&&confidence<=100,"confidence number value must be an integer 0..100");return}if(typeof confidence=="string"){const normalizedConfidence=confidence.trim().toLowerCase(),isKnownTextConfidence=normalizedConfidence==="med"||CONFIDENCE_TEXT_VALUES.includes(normalizedConfidence);assertItemMetadataCondition(isKnownTextConfidence,`confidence string value must be one of: ${[...CONFIDENCE_TEXT_VALUES,"med"].join(", ")}`);return}assertItemMetadataCondition(!1,"confidence must be a number or string")}}function assertSeverityItemMetadataField(record){const severity=record.severity;if(severity===void 0)return;typeof severity!="string"&&validationError("severity must be a string");const normalizedSeverity=severity.trim().toLowerCase(),isKnownSeverity=normalizedSeverity==="med"||ISSUE_SEVERITY_VALUES.includes(normalizedSeverity);assertItemMetadataCondition(isKnownSeverity,`severity value must be one of: ${[...ISSUE_SEVERITY_VALUES,"med"].join(", ")}`)}function assertRegressionItemMetadataField(record){record.regression!==void 0&&typeof record.regression!="boolean"&&validationError("regression must be a boolean")}function assertReminderEntries(record){const reminders=record.reminders;if(reminders!==void 0){assertItemMetadataCondition(Array.isArray(reminders),"reminders must be an array");for(const reminder of reminders){const reminderRecord=requireItemMetadataRecord(reminder,"reminders entries must be objects");assertItemMetadataCondition(typeof reminderRecord.at=="string","reminder.at must be a string"),assertItemMetadataCondition(isTimestampLiteral(reminderRecord.at),"reminder.at must be a valid ISO timestamp"),assertItemMetadataCondition(typeof reminderRecord.text=="string","reminder.text must be a string"),assertItemMetadataCondition(reminderRecord.text.trim().length>0,"reminder.text must not be empty")}}}function assertEventStringFields(eventRecord){for(const stringField of["title","description","location","timezone"])eventRecord[stringField]!==void 0&&(assertItemMetadataCondition(typeof eventRecord[stringField]=="string",`event.${stringField} must be a string`),assertItemMetadataCondition(eventRecord[stringField].trim().length>0,`event.${stringField} must not be empty`))}function assertEventRecurrence(eventRecord){eventRecord.recurrence!==void 0&&(assertValidRecurrenceRule(eventRecord.recurrence),eventRecord.recurrence.until!==void 0&&assertItemMetadataCondition(compareTimestampStrings(eventRecord.recurrence.until,eventRecord.start_at)>=0,"event.recurrence.until must be at or after event.start_at"))}function assertCalendarEventEntry(event){const eventRecord=requireItemMetadataRecord(event,"events entries must be objects");assertItemMetadataCondition(typeof eventRecord.start_at=="string","event.start_at must be a string"),assertItemMetadataCondition(isTimestampLiteral(eventRecord.start_at),"event.start_at must be a valid ISO timestamp"),eventRecord.end_at!==void 0&&(assertItemMetadataCondition(typeof eventRecord.end_at=="string","event.end_at must be a string"),assertItemMetadataCondition(isTimestampLiteral(eventRecord.end_at),"event.end_at must be a valid ISO timestamp"),assertItemMetadataCondition(compareTimestampStrings(eventRecord.end_at,eventRecord.start_at)>0,"event.end_at must be after event.start_at")),assertEventStringFields(eventRecord),eventRecord.all_day!==void 0&&assertItemMetadataCondition(typeof eventRecord.all_day=="boolean","event.all_day must be a boolean"),assertEventRecurrence(eventRecord)}function assertCalendarEvents(record){const events=record.events;if(events!==void 0){assertItemMetadataCondition(Array.isArray(events),"events must be an array");for(const event of events)assertCalendarEventEntry(event)}}function assertOptionalStringFields(record){for(const fieldName of["source_type","source_owner","design","external_ref"]){const value=record[fieldName];value!==void 0&&assertItemMetadataCondition(typeof value=="string",`${fieldName} must be a string`)}}function assertTypeOptionsField(record){const typeOptions=record.type_options;if(typeOptions===void 0)return;const typeOptionsRecord=requireItemMetadataRecord(typeOptions,"type_options must be an object");for(const[optionKey,optionValue]of Object.entries(typeOptionsRecord))assertItemMetadataCondition(optionKey.trim().length>0,"type_options keys must be non-empty"),assertItemMetadataCondition(typeof optionValue=="string","type_options values must be strings"),assertItemMetadataCondition(optionValue.trim().length>0,"type_options values must be non-empty strings")}function coerceRuntimeItemMetadataFields(record,itemType,runtimeContext){if(runtimeContext?.fieldRegistry)for(const definition of runtimeContext.fieldRegistry.definitions){const fieldValue=record[definition.metadata_key];if(fieldValue===void 0){runtimeFieldRequiredForType(definition,itemType)&&validationError(`missing required schema field: ${definition.metadata_key}`);continue}try{record[definition.metadata_key]=coerceRuntimeFieldValue(definition,fieldValue,`metadata field "${definition.metadata_key}"`,"metadata")}catch(error){validationError(String(error?.message).replace(/^Invalid\s+/u,""))}}}function assertRuntimeUnknownItemMetadataFields(record,runtimeContext){if(!runtimeContext||runtimeContext.unknownFieldPolicy==="allow")return;const knownKeys=buildKnownItemMetadataKeys(runtimeContext),unknownKeys=Object.keys(record).filter(key=>!knownKeys.has(key)).sort((left,right)=>left.localeCompare(right));unknownKeys.length!==0&&(runtimeContext.unknownFieldPolicy==="reject"?validationError(`unknown schema fields are not allowed: ${unknownKeys.join(", ")}`):runtimeContext.onWarning?.(`item_unknown_schema_fields:${unknownKeys.join(",")}`))}function assertValidItemMetadata(itemMetadata,runtimeContext){const record=requireItemMetadataRecord(itemMetadata,"item metadata must be an object"),itemType=assertRequiredItemMetadataFields(record);assertStatusItemMetadataField(record,runtimeContext),assertPriorityAndTags(record),assertConfidenceItemMetadataField(record),assertSeverityItemMetadataField(record),assertRegressionItemMetadataField(record),assertTimestampField(record,"created_at"),assertTimestampField(record,"updated_at"),record.deadline!==void 0&&assertTimestampField(record,"deadline"),assertReminderEntries(record),assertCalendarEvents(record),assertOptionalTimestampString(record,"closed_at","closed_at"),assertOptionalTimestampString(record,"completed_at","completed_at"),assertOptionalStringFields(record),assertTypeOptionsField(record),coerceRuntimeItemMetadataFields(record,itemType,runtimeContext),assertRuntimeUnknownItemMetadataFields(record,runtimeContext)}function sortDependencies(values){if(!(!values||values.length===0))return[...values].map((value,index)=>(assertItemMetadataCondition(value.created_at===void 0||typeof value.created_at=="string"&&isRfc3339DateTime(value.created_at),`dependencies.${index}.created_at requires a valid timestamp; restore the dependency timestamp from its source record`),{id:value.id.trim(),kind:value.kind,created_at:value.created_at,author:value.author?.trim()||void 0,source_kind:value.source_kind?.trim()||void 0,author_source:value.author_source})).sort((a,b)=>{const byCreated=compareTimestampStrings(a.created_at??"",b.created_at??"");if(byCreated!==0)return byCreated;const byId=a.id.localeCompare(b.id);if(byId!==0)return byId;const byKind=a.kind.localeCompare(b.kind);return byKind!==0?byKind:(a.source_kind??"").localeCompare(b.source_kind??"")})}function sortLogValues(values){if(!(!values||values.length===0))return[...values].sort((a,b)=>{const byCreated=compareTimestampStrings(a.created_at,b.created_at);if(byCreated!==0)return byCreated;const byText=a.text.localeCompare(b.text);return byText!==0?byText:a.author.localeCompare(b.author)})}function sortReminders(values){if(!values||values.length===0)return;const normalized=[...values].map(value=>({at:value.at,text:value.text.trim()})).filter(value=>value.text.length>0).sort((a,b)=>{const byAt=compareTimestampStrings(a.at,b.at);return byAt!==0?byAt:a.text.localeCompare(b.text)});return normalized.length===0?void 0:normalized}function normalizeRecurrenceRule(value){if(!value)return;const normalizedFrequency=value.freq.trim().toLowerCase();if(!RECURRENCE_FREQUENCY_VALUES.includes(normalizedFrequency))return;const byWeekday=Array.from(new Set((value.by_weekday??[]).map(weekday=>weekday.trim().toLowerCase()).filter(weekday=>RECURRENCE_WEEKDAY_VALUES.includes(weekday)))).sort((a,b)=>weekdayOrderIndex(a)-weekdayOrderIndex(b)),byMonthDay=Array.from(new Set((value.by_month_day??[]).filter(day=>Number.isInteger(day)&&day>=1&&day<=31).map(day=>day))).sort((a,b)=>a-b),exdates=Array.from(new Set((value.exdates??[]).map(timestamp=>timestamp.trim()).filter(timestamp=>isTimestampLiteral(timestamp)))).sort((a,b)=>compareTimestampStrings(a,b)),normalized={freq:normalizedFrequency,interval:value.interval!==void 0&&value.interval>1?value.interval:void 0,count:value.count,until:value.until?.trim()||void 0,by_weekday:byWeekday.length>0?byWeekday:void 0,by_month_day:byMonthDay.length>0?byMonthDay:void 0,exdates:exdates.length>0?exdates:void 0};for(const[key,fieldValue]of Object.entries(normalized))fieldValue===void 0&&delete normalized[key];return normalized}function sortEvents(values){return!Array.isArray(values)||values.length===0?void 0:[...values].map(normalizeCalendarEvent).sort(compareCalendarEvents)}function normalizeCalendarEvent(value){const event={start_at:value.start_at,end_at:value.end_at||void 0,title:value.title?.trim()||void 0,description:value.description?.trim()||void 0,location:value.location?.trim()||void 0,all_day:value.all_day,timezone:value.timezone?.trim()||void 0,recurrence:normalizeRecurrenceRule(value.recurrence)};return deleteUndefinedFields(event),event}function compareCalendarEvents(a,b){return firstNonZeroComparison([compareTimestampStrings(a.start_at,b.start_at),(a.end_at??"").localeCompare(b.end_at??""),(a.title??"").localeCompare(b.title??""),+!!a.all_day-+!!b.all_day,(a.timezone??"").localeCompare(b.timezone??""),(a.location??"").localeCompare(b.location??""),(a.description??"").localeCompare(b.description??""),JSON.stringify(a.recurrence??{}).localeCompare(JSON.stringify(b.recurrence??{}))])}function normalizeFiles(values){if(!(!values||values.length===0))return values.map(value=>({path:normalizePathValue(value.path),scope:value.scope,note:value.note?.trim()||void 0}))}function normalizeTestRunSummaries(values){if(!values||values.length===0)return;const normalized=values.map(normalizeTestRunSummary).filter(value=>value.run_id.length>0&&value.started_at.length>0&&value.finished_at.length>0&&value.recorded_at.length>0).sort((a,b)=>firstNonZeroComparison([compareTimestampStrings(a.recorded_at,b.recorded_at),a.run_id.localeCompare(b.run_id),a.kind.localeCompare(b.kind)]));return normalized.length>0?normalized:void 0}function normalizeNonNegativeInteger(value){return typeof value=="number"&&Number.isFinite(value)&&value>=0?Math.floor(value):void 0}function normalizePositiveInteger(value){return typeof value=="number"&&Number.isFinite(value)&&value>=1?Math.floor(value):void 0}function stringOrEmpty(value){return typeof value=="string"?value:""}function normalizeTestRunMeasurements(value){if(!Array.isArray(value))return;const normalized=value.filter(measurement=>measurement!==null&&typeof measurement=="object"&&typeof measurement.name=="string"&&measurement.name.trim().length>0&&typeof measurement.value=="number"&&Number.isFinite(measurement.value)&&typeof measurement.recorded_at=="string"&&measurement.recorded_at.trim().length>0).map(measurement=>({name:measurement.name.trim(),value:measurement.value,unit:typeof measurement.unit=="string"&&measurement.unit.trim()||void 0,threshold:typeof measurement.threshold=="number"&&Number.isFinite(measurement.threshold)?measurement.threshold:void 0,recorded_at:measurement.recorded_at.trim()})),deduplicated=[...new Map(normalized.map(measurement=>[measurement.name,measurement])).values()].sort((left,right)=>left.name.localeCompare(right.name)).slice(0,32);return deduplicated.length>0?deduplicated:void 0}function normalizeTestRunEnum(value,allowedValues){return typeof value=="string"&&allowedValues.has(value)?value:void 0}function normalizeTestRunExecutions(values){if(!Array.isArray(values))return;const executions=values.filter(execution=>execution&&typeof execution.command=="string"&&execution.command.trim().length>0).slice(0,32).map(execution=>({command:execution.command.trim(),requested_pm_context_mode:normalizeTestRunEnum(execution.requested_pm_context_mode,LINKED_TEST_PM_CONTEXT_MODE_VALUES),pm_context_mode:normalizeTestRunEnum(execution.pm_context_mode,LINKED_TEST_PM_CONTEXT_MODE_VALUES),workspace_context_mode:normalizeTestRunEnum(execution.workspace_context_mode,LINKED_TEST_WORKSPACE_CONTEXT_MODE_VALUES),trust_reason:normalizeTestRunEnum(execution.trust_reason,LINKED_TEST_TRUST_REASON_VALUES)}));return executions.length>0?executions:void 0}function normalizeTestRunSummary(value){const runId=typeof value.run_id=="string"?value.run_id.trim():"",kind=value.kind==="test"||value.kind==="test-all"?value.kind:"test",status=ITEM_TEST_RUN_STATUS_VALUES.has(value.status)?value.status:"failed",summary={run_id:runId,kind,status,started_at:stringOrEmpty(value.started_at),finished_at:stringOrEmpty(value.finished_at),recorded_at:stringOrEmpty(value.recorded_at),attempt:normalizePositiveInteger(value.attempt),resumed_from:value.resumed_from?.trim()||void 0,passed:normalizeNonNegativeInteger(value.passed)??0,failed:normalizeNonNegativeInteger(value.failed)??0,skipped:normalizeNonNegativeInteger(value.skipped)??0,items:normalizeNonNegativeInteger(value.items),linked_tests:normalizeNonNegativeInteger(value.linked_tests),fail_on_skipped_triggered:value.fail_on_skipped_triggered===!0?!0:void 0,measurements:normalizeTestRunMeasurements(value.measurements),executions:normalizeTestRunExecutions(value.executions)};return deleteUndefinedFields(summary),summary}function sortTests(values){if(!(!Array.isArray(values)||values.length===0))return values.map(normalizeLinkedTest)}function normalizeTrimmedStringList(value){if(!Array.isArray(value))return;const normalized=[...new Set(value.filter(entry=>typeof entry=="string").map(entry=>entry.trim()).filter(entry=>entry.length>0))].sort((a,b)=>a.localeCompare(b));return normalized.length>0?normalized:void 0}function isPlainObjectRecord(value){if(!value||typeof value!="object"||Array.isArray(value))return!1;const prototype=Object.getPrototypeOf(value);return prototype===Object.prototype||prototype===null}function isUnsafeObjectKey(key){return key==="__proto__"||key==="constructor"||key==="prototype"}function normalizeStringRecord(value){if(!isPlainObjectRecord(value))return;const entries=Object.entries(value).map(([key,recordValue])=>[key.trim(),String(recordValue).trim()]).filter(([key,recordValue])=>key.length>0&&!isUnsafeObjectKey(key)&&recordValue.length>0).sort(([left],[right])=>left.localeCompare(right));return entries.length>0?Object.fromEntries(entries):void 0}function normalizeNumericRecord(value){if(!isPlainObjectRecord(value))return;const entries=Object.entries(value).map(([key,recordValue])=>[key.trim(),Number(recordValue)]).filter(([key,recordValue])=>key.length>0&&!isUnsafeObjectKey(key)&&Number.isFinite(recordValue)).sort(([left],[right])=>left.localeCompare(right));return entries.length>0?Object.fromEntries(entries):void 0}function normalizeLinkedTestContextMode(value){const normalized=value?.trim().toLowerCase();if(!(!normalized||!LINKED_TEST_PM_CONTEXT_MODE_VALUES.has(normalized)))return normalized}function normalizeLinkedTestWorkspaceContextMode(value){const normalized=value?.trim().toLowerCase();if(!(!normalized||!LINKED_TEST_WORKSPACE_CONTEXT_MODE_VALUES.has(normalized)))return normalized}function normalizeLinkedTestProvenance(value,invalid){if(invalid===!0)return{provenance_invalid:!0};if(value===void 0)return{};if(!isPlainObjectRecord(value))return{provenance_invalid:!0};const author=trimStringOrUndefined(value.author),createdAt=trimStringOrUndefined(value.created_at),sourceKind=value.source_kind;return!author||!createdAt||!isTimestampLiteral(createdAt)||sourceKind!=="local_mutation"&&sourceKind!=="merge_union"?{provenance_invalid:!0}:{provenance:{author,created_at:createdAt,source_kind:sourceKind,source_ref:trimStringOrUndefined(value.source_ref)}}}function normalizeLinkedTest(value){const test={command:value.command?.trim()||void 0,path:value.path?normalizePathValue(value.path):void 0,scope:value.scope,timeout_seconds:typeof value.timeout_seconds=="number"&&Number.isFinite(value.timeout_seconds)&&value.timeout_seconds>0?value.timeout_seconds:void 0,pm_context_mode:normalizeLinkedTestContextMode(value.pm_context_mode),workspace_context_mode:normalizeLinkedTestWorkspaceContextMode(value.workspace_context_mode),...normalizeLinkedTestProvenance(value.provenance,value.provenance_invalid),updated_by:trimStringOrUndefined(value.updated_by),updated_at:trimStringOrUndefined(value.updated_at),env_set:normalizeStringRecord(value.env_set),env_clear:normalizeTrimmedStringList(value.env_clear),shared_host_safe:value.shared_host_safe===!0?!0:void 0,assert_stdout_contains:normalizeTrimmedStringList(value.assert_stdout_contains),assert_stdout_regex:normalizeTrimmedStringList(value.assert_stdout_regex),assert_stderr_contains:normalizeTrimmedStringList(value.assert_stderr_contains),assert_stderr_regex:normalizeTrimmedStringList(value.assert_stderr_regex),assert_stdout_min_lines:normalizeNonNegativeInteger(value.assert_stdout_min_lines),assert_json_field_equals:normalizeStringRecord(value.assert_json_field_equals),assert_json_field_gte:normalizeNumericRecord(value.assert_json_field_gte),note:value.note?.trim()||void 0};return deleteUndefinedFields(test),test}function sortDocs(values){if(!(!values||values.length===0))return[...values].map(value=>({path:normalizePathValue(value.path),scope:value.scope,note:value.note?.trim()||void 0})).sort((a,b)=>{const byScope=a.scope.localeCompare(b.scope);if(byScope!==0)return byScope;const byPath=a.path.localeCompare(b.path);return byPath!==0?byPath:(a.note??"").localeCompare(b.note??"")})}function trimStringOrUndefined(value){if(typeof value!="string")return;const trimmed=value.trim();return trimmed.length>0?trimmed:void 0}function normalizePlanStepLinks(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,id=trimStringOrUndefined(record.id),kind=trimStringOrUndefined(record.kind);if(!id||!kind)continue;const link={id,kind},note=trimStringOrUndefined(record.note);note&&(link.note=note),record.required_before_step===!0&&(link.required_before_step=!0),out.push(link)}return out.length>0?out:void 0}function normalizePlanStepFiles(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,path=trimStringOrUndefined(record.path);if(!path)continue;const file={path:normalizePathValue(path)};(record.scope==="project"||record.scope==="global")&&(file.scope=record.scope);const note=trimStringOrUndefined(record.note);note&&(file.note=note),out.push(file)}return out.length>0?out:void 0}function normalizePlanStepTests(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,command=trimStringOrUndefined(record.command),path=trimStringOrUndefined(record.path);if(!command&&!path)continue;const test={};command&&(test.command=command),path&&(test.path=normalizePathValue(path));const note=trimStringOrUndefined(record.note);note&&(test.note=note),out.push(test)}return out.length>0?out:void 0}function normalizePlanStepDocs(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,path=trimStringOrUndefined(record.path);if(!path)continue;const doc={path:normalizePathValue(path)};(record.scope==="project"||record.scope==="global")&&(doc.scope=record.scope);const note=trimStringOrUndefined(record.note);note&&(doc.note=note),out.push(doc)}return out.length>0?out:void 0}function normalizePlanStepEntry(entry){if(entry===null||typeof entry!="object")return;const record=entry,id=trimStringOrUndefined(record.id),title=trimStringOrUndefined(record.title),statusRaw=trimStringOrUndefined(record.status),status=statusRaw&&PLAN_STEP_STATUS_SET.has(statusRaw)?statusRaw:void 0,order=coerceFiniteNumber(record.order)??Number.NaN,created_at=typeof record.created_at=="string"?record.created_at:"",updated_at=typeof record.updated_at=="string"?record.updated_at:"";if(!id||!title||!status||!Number.isFinite(order)||!created_at||!updated_at)return;const step={id,order,title,status,created_at,updated_at};return applyPlanStepOptionalFields(step,record),step}function applyPlanStepOptionalFields(step,record){const stringFields=[["body","body"],["owner","owner"],["evidence","evidence"],["blocked_reason","blocked_reason"],["superseded_by","superseded_by"]];for(const[target,source]of stringFields){const value=trimStringOrUndefined(record[source]);value&&(step[target]=value)}const completedAt=typeof record.completed_at=="string"?record.completed_at:void 0;completedAt&&completedAt.length>0&&(step.completed_at=completedAt);const collectionFields=[["linked_items","linked_items",normalizePlanStepLinks],["files","files",normalizePlanStepFiles],["tests","tests",normalizePlanStepTests],["docs","docs",normalizePlanStepDocs]];for(const[target,source,normalize]of collectionFields){const value=normalize(record[source]);value&&(step[target]=value)}}function normalizePlanSteps(value){if(!Array.isArray(value))return;const out=value.flatMap(entry=>{const step=normalizePlanStepEntry(entry);return step?[step]:[]});return out.sort((left,right)=>left.order-right.order),out.length>0?out:void 0}function normalizePlanDecisions(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,ts=typeof record.ts=="string"?record.ts:"",author=typeof record.author=="string"?record.author:"",decision=trimStringOrUndefined(record.decision);if(!ts||!author||!decision)continue;const item={ts,author,decision},rationale=trimStringOrUndefined(record.rationale);rationale&&(item.rationale=rationale);const evidence=trimStringOrUndefined(record.evidence);evidence&&(item.evidence=evidence);const stepId=trimStringOrUndefined(record.step_id);stepId&&(item.step_id=stepId),out.push(item)}return out.length>0?out:void 0}function normalizePlanDiscoveries(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,ts=typeof record.ts=="string"?record.ts:"",author=typeof record.author=="string"?record.author:"",text=trimStringOrUndefined(record.text);if(!ts||!author||!text)continue;const item={ts,author,text},stepId=trimStringOrUndefined(record.step_id);stepId&&(item.step_id=stepId),out.push(item)}return out.length>0?out:void 0}function normalizePlanValidation(value){if(!Array.isArray(value))return;const out=[];for(const entry of value){if(entry===null||typeof entry!="object")continue;const record=entry,text=trimStringOrUndefined(record.text);if(!text)continue;const item={text},command=trimStringOrUndefined(record.command);command&&(item.command=command);const expected=trimStringOrUndefined(record.expected);expected&&(item.expected=expected),out.push(item)}return out.length>0?out:void 0}function normalizeTypeOptions(values){if(!values)return;const normalizedEntries=Object.entries(values).map(([key,value])=>[key.trim(),value.trim()]).filter(([key,value])=>key.length>0&&value.length>0).sort((left,right)=>left[0].localeCompare(right[0]));if(normalizedEntries.length!==0)return Object.fromEntries(normalizedEntries)}function normalizeBody(body){let start=0;for(;start<body.length&&body[start]===`
|
|
2
2
|
`;)start+=1;return body.slice(start).trimEnd()}function normalizeConfidenceValue(value){if(value===void 0)return;if(typeof value=="number")return value;const normalized=value.trim().toLowerCase();if(normalized==="med")return"medium";if(CONFIDENCE_TEXT_VALUES.includes(normalized))return normalized}function normalizeSeverityValue(value){if(value===void 0)return;const normalized=value.trim().toLowerCase();if(normalized==="med")return"medium";if(ISSUE_SEVERITY_VALUES.includes(normalized))return normalized}function emptyStringToUndefined(value){return value||void 0}function copyExtensionItemMetadataFields(normalized,source){const targetRecord=normalized,sourceRecord=source;for(const[key,value]of Object.entries(sourceRecord))isUnsafeObjectKey(key)||Object.prototype.hasOwnProperty.call(targetRecord,key)||value===void 0||(targetRecord[key]=value)}function coerceNormalizedRuntimeFields(normalized,runtimeContext){if(!runtimeContext?.fieldRegistry)return;const record=normalized;for(const definition of runtimeContext.fieldRegistry.definitions){const currentValue=record[definition.metadata_key];currentValue!==void 0&&(record[definition.metadata_key]=coerceRuntimeFieldValue(definition,currentValue,`metadata field "${definition.metadata_key}"`,"metadata"))}}function assertNormalizedUnknownFields(normalized,runtimeContext){if(!runtimeContext||runtimeContext.unknownFieldPolicy==="allow")return;const knownKeys=buildKnownItemMetadataKeys(runtimeContext),unknownKeys=Object.keys(normalized).filter(key=>!knownKeys.has(key)).sort((left,right)=>left.localeCompare(right));unknownKeys.length>0&&runtimeContext.unknownFieldPolicy==="reject"&&validationError(`unknown schema fields are not allowed: ${unknownKeys.join(", ")}`),unknownKeys.length>0&&runtimeContext.onWarning?.(`item_unknown_schema_fields:${unknownKeys.join(",")}`)}function normalizeItemMetadata(itemMetadata,options={}){const runtimeContext=resolveRuntimeSchemaValidationContext(options),normalizedStatus=normalizeStatusInput(itemMetadata.status,runtimeContext?.statusRegistry)??itemMetadata.status,tags=Array.from(new Set((Array.isArray(itemMetadata.tags)?itemMetadata.tags:[]).filter(tag=>typeof tag=="string").map(tag=>tag.trim().toLowerCase()).filter(Boolean))).sort((a,b)=>a.localeCompare(b)),normalized={id:itemMetadata.id,title:itemMetadata.title,description:itemMetadata.description,type:itemMetadata.type,pm_format_version:normalizeItemFormatVersion(itemMetadata.pm_format_version),source_type:trimStringOrUndefined(itemMetadata.source_type),type_options:normalizeTypeOptions(itemMetadata.type_options),status:normalizedStatus,priority:itemMetadata.priority,tags,created_at:itemMetadata.created_at,updated_at:itemMetadata.updated_at,dependencies:sortDependencies(itemMetadata.dependencies),comments:sortLogValues(itemMetadata.comments),notes:sortLogValues(itemMetadata.notes),learnings:sortLogValues(itemMetadata.learnings),files:normalizeFiles(itemMetadata.files),tests:sortTests(itemMetadata.tests),test_runs:normalizeTestRunSummaries(itemMetadata.test_runs),docs:sortDocs(itemMetadata.docs),deadline:emptyStringToUndefined(itemMetadata.deadline),reminders:sortReminders(itemMetadata.reminders),events:sortEvents(itemMetadata.events),closed_at:emptyStringToUndefined(itemMetadata.closed_at),completed_at:emptyStringToUndefined(itemMetadata.completed_at),assignee:trimStringOrUndefined(itemMetadata.assignee),claim_principal:trimStringOrUndefined(itemMetadata.claim_principal),source_owner:trimStringOrUndefined(itemMetadata.source_owner),author:emptyStringToUndefined(itemMetadata.author),estimated_minutes:itemMetadata.estimated_minutes,acceptance_criteria:itemMetadata.acceptance_criteria??void 0,design:itemMetadata.design??void 0,external_ref:itemMetadata.external_ref??void 0,definition_of_ready:trimStringOrUndefined(itemMetadata.definition_of_ready),order:itemMetadata.order,goal:trimStringOrUndefined(itemMetadata.goal),objective:trimStringOrUndefined(itemMetadata.objective),value:trimStringOrUndefined(itemMetadata.value),impact:trimStringOrUndefined(itemMetadata.impact),outcome:trimStringOrUndefined(itemMetadata.outcome),why_now:trimStringOrUndefined(itemMetadata.why_now),parent:trimStringOrUndefined(itemMetadata.parent),reviewer:trimStringOrUndefined(itemMetadata.reviewer),risk:itemMetadata.risk??void 0,confidence:normalizeConfidenceValue(itemMetadata.confidence),sprint:trimStringOrUndefined(itemMetadata.sprint),release:trimStringOrUndefined(itemMetadata.release),blocked_by:trimStringOrUndefined(itemMetadata.blocked_by),blocked_reason:trimStringOrUndefined(itemMetadata.blocked_reason),unblock_note:trimStringOrUndefined(itemMetadata.unblock_note),reporter:trimStringOrUndefined(itemMetadata.reporter),severity:normalizeSeverityValue(itemMetadata.severity),environment:trimStringOrUndefined(itemMetadata.environment),repro_steps:trimStringOrUndefined(itemMetadata.repro_steps),resolution:trimStringOrUndefined(itemMetadata.resolution),expected_result:trimStringOrUndefined(itemMetadata.expected_result),actual_result:trimStringOrUndefined(itemMetadata.actual_result),affected_version:trimStringOrUndefined(itemMetadata.affected_version),fixed_version:trimStringOrUndefined(itemMetadata.fixed_version),component:trimStringOrUndefined(itemMetadata.component),regression:itemMetadata.regression,customer_impact:trimStringOrUndefined(itemMetadata.customer_impact),close_reason:emptyStringToUndefined(itemMetadata.close_reason),plan_mode:trimStringOrUndefined(itemMetadata.plan_mode),plan_scope:trimStringOrUndefined(itemMetadata.plan_scope),plan_harness:trimStringOrUndefined(itemMetadata.plan_harness),plan_resume_context:trimStringOrUndefined(itemMetadata.plan_resume_context),plan_steps:normalizePlanSteps(itemMetadata.plan_steps),plan_decisions:normalizePlanDecisions(itemMetadata.plan_decisions),plan_discoveries:normalizePlanDiscoveries(itemMetadata.plan_discoveries),plan_validation:normalizePlanValidation(itemMetadata.plan_validation)};return copyExtensionItemMetadataFields(normalized,itemMetadata),coerceNormalizedRuntimeFields(normalized,runtimeContext),assertNormalizedUnknownFields(normalized,runtimeContext),deleteUndefinedFields(normalized),normalized}function orderItemMetadata(itemMetadata){return orderObject(itemMetadata,ITEM_METADATA_KEY_ORDER)}function findJsonObjectEnd(content){let depth=0,inString=!1,escaped=!1;for(let i=0;i<content.length;i+=1){const char=content[i];if(inString){if(escaped){escaped=!1;continue}if(char==="\\"){escaped=!0;continue}char==='"'&&(inString=!1);continue}if(char==='"'){inString=!0;continue}if(char==="{"){depth+=1;continue}if(char==="}"&&(depth-=1,depth===0))return i}return-1}function splitFrontMatter(content){if(!content.startsWith("{"))return{frontMatter:"",body:content};const end=findJsonObjectEnd(content);if(end<0)return{frontMatter:"",body:content};const frontMatter=content.slice(0,end+1),body=content.slice(end+1).replace(/^\r?\n+/,"");return{frontMatter,body}}function stripLeadingYamlDocument(content){const normalizedContent=content.charCodeAt(0)===65279?content.slice(1):content,opener=normalizedContent.match(/^[ \t]*---[ \t]*(?:\r?\n|$)/);if(!opener)return{content:normalizedContent,stripped:!1};let cursor=opener[0].length;for(;cursor<normalizedContent.length;){const nextNewline=normalizedContent.indexOf(`
|
|
3
3
|
`,cursor),lineEnd=nextNewline===-1?normalizedContent.length:nextNewline,line=normalizedContent.slice(cursor,lineEnd).replace(/\r$/,""),afterLine=nextNewline===-1?lineEnd:lineEnd+1;if(line.trim()==="---")return{content:normalizedContent.slice(afterLine).replace(/^\s+/,""),stripped:!0};cursor=afterLine}return{content:normalizedContent,stripped:!1}}function normalizeParsedItemMetadata(itemMetadata,options){return normalizeItemMetadata(itemMetadata,{...options,onWarning:void 0})}function parseJsonMarkdownItemDocument(content,runtimeContext,options={}){const normalized=stripLeadingYamlDocument(content);normalized.stripped&&options.onWarning?.("json_markdown_leading_yaml_frontmatter_ignored");const{frontMatter,body}=splitFrontMatter(normalized.content);frontMatter||(content.trimStart().startsWith("{")&&documentSyntaxError("json_markdown","JSON front matter is not valid JSON"),documentSyntaxError("json_markdown","JSON Markdown item document is missing JSON front matter"));let parsed;try{parsed=JSON.parse(frontMatter)}catch{documentSyntaxError("json_markdown","JSON front matter is not valid JSON")}return assertSupportedItemFormat(parsed,options.requireSupportedFormat),assertValidItemMetadata(parsed,runtimeContext),{metadata:normalizeParsedItemMetadata(parsed,options),body:normalizeBody(body)}}function parseToonItemDocument(content,runtimeContext,options={}){let parsed;try{parsed=decodeToonItemContent(content).value}catch{documentSyntaxError("toon","TOON item document is not valid TOON")}assertItemMetadataCondition(typeof parsed=="object"&&parsed!==null&&!Array.isArray(parsed),"TOON item document must be an object");const record=parsed;if(assertSupportedItemFormat(Object.prototype.hasOwnProperty.call(record,"front_matter")?record.front_matter:record,options.requireSupportedFormat),!REQUIRED_STRING_FIELDS.some(fieldName=>Object.prototype.hasOwnProperty.call(record,fieldName))&&!Object.prototype.hasOwnProperty.call(record,"front_matter")&&documentSyntaxError("toon","TOON input does not have the shape of an item document"),Object.prototype.hasOwnProperty.call(record,"front_matter"))return assertValidItemMetadata(record.front_matter,runtimeContext),assertItemMetadataCondition(record.body===void 0||typeof record.body=="string","TOON item document body must be a string"),{metadata:normalizeParsedItemMetadata(record.front_matter,options),body:normalizeBody(typeof record.body=="string"?record.body:"")};const{body,...itemMetadataRecord}=record;return assertItemMetadataCondition(body===void 0||typeof body=="string","TOON item document body must be a string"),assertValidItemMetadata(itemMetadataRecord,runtimeContext),{metadata:normalizeParsedItemMetadata(itemMetadataRecord,options),body:normalizeBody(typeof body=="string"?body:"")}}function serializeJsonMarkdownItemDocument(document,options={}){const normalizedMetadata=normalizeItemMetadata(document.metadata,options),orderedMetadata=orderItemMetadata(normalizedMetadata),normalizedBody=normalizeBody(document.body??"");assertWellFormedItemText(JSON.parse(JSON.stringify(orderedMetadata))),assertWellFormedItemText({body:normalizedBody});const serializedMetadata=JSON.stringify(orderedMetadata,null,2);return normalizedBody?`${serializedMetadata}
|
|
4
4
|
|
package/dist/core/lock/lock.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ declare function isErrno(error:unknown,code:string):boolean;
|
|
|
36
36
|
declare function isLockCreateContention(error:unknown,lockPath:string,platform?:NodeJS.Platform):Promise<boolean>;
|
|
37
37
|
declare function buildLockPayload(id:string,owner:string,ttlSeconds:number,token?:string):LockInfo;
|
|
38
38
|
declare function isStaleLock(info:LockInfo | null,ttlSeconds:number):boolean;
|
|
39
|
+
/** Observe a built-in lock's owner lease without acquiring it or changing storage. */
|
|
40
|
+
export declare function hasUnexpiredLockOwner(pmRoot:string,id:string,ownerPrefix:string):Promise<boolean>;
|
|
39
41
|
declare function lockOwnerSuffix(info:LockInfo | null):string;
|
|
40
42
|
/** Resolves the effective bounded wait budget for a contended lock: the PM_LOCK_WAIT_MS environment override wins when it parses as a non-negative integer, then the caller-provided budget (settings `locks.wait_ms`), then 0 (fail-fast, the pre-wait behavior). */
|
|
41
43
|
declare function resolveLockWaitMs(waitMs:number | undefined):number;
|
|
@@ -80,9 +82,14 @@ removeConfirmedStaleLock:typeof removeConfirmedStaleLock;
|
|
|
80
82
|
* Acquire a token-owned tracker lock with bounded contention waiting and
|
|
81
83
|
* explicit stale-owner policy. Background consumers may disable creation of
|
|
82
84
|
* parent directories so acquiring or retrying a lock cannot revive removed
|
|
83
|
-
* storage.
|
|
85
|
+
* storage. An explicit maxWaitMs caps contention retries even when the process
|
|
86
|
+
* environment requests a longer wait. Extension overrides receive that ceiling
|
|
87
|
+
* and retain responsibility for their own lifecycle.
|
|
84
88
|
*/
|
|
85
89
|
export declare function acquireLock(pmRoot:string,id:string,ttlSeconds:number,owner:string,force?:boolean,forceRequiredForStaleLock?:boolean,waitMs?:number,options?:{
|
|
90
|
+
/** Allow lock acquisition to initialize missing lock directories. */
|
|
86
91
|
createParentDirectories?:boolean;
|
|
92
|
+
/** Ceiling on the effective retry budget, including PM_LOCK_WAIT_MS. */
|
|
93
|
+
maxWaitMs?:number;
|
|
87
94
|
}):Promise<() => Promise<void>>;
|
|
88
95
|
export {};
|
package/dist/core/lock/lock.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
-
`,"utf8")}finally{await handle.close()}}catch(error){throw await unlinkLockWithHook(lockPath,"lock:release"),error}}finally{await releaseCleanupGate()}await emitLockWriteHook(lockPath,"lock:create")}async function unlinkLockWithHook(lockPath,op){try{return await fs.unlink(lockPath),await emitLockWriteHook(lockPath,op),!0}catch{return!1}}async function releaseOwnedLock(lockPath,id,owner,token){const startedAtMs=Date.now();let backoffMs=LOCK_WAIT_INITIAL_DELAY_MS;for(;;){const releaseCleanupGate=await acquireStaleCleanupGate(lockPath,id);if(releaseCleanupGate!==null){try{const current2=await readLockInfo(lockPath,!1);isOwnedLock(current2.info,id,owner,token)&&await unlinkLockWithHook(lockPath,"lock:release")}finally{await releaseCleanupGate()}return}const current=await readLockInfo(lockPath,!1);if(!isOwnedLock(current.info,id,owner,token))return;const elapsedMs=Date.now()-startedAtMs;if(elapsedMs>=LOCK_RELEASE_GATE_WAIT_MS)return;await sleepWithJitter(Math.min(backoffMs,LOCK_RELEASE_GATE_WAIT_MS-elapsedMs)),backoffMs=Math.min(backoffMs*2,LOCK_WAIT_MAX_DELAY_MS)}}function isOwnedLock(info,id,owner,token){return info?.id===id&&info.pid===process.pid&&info.owner===owner&&info.token===token}function isStaleLock(info,ttlSeconds){const createdAtMs=info?.created_at?Date.parse(info.created_at):Number.NaN;return(Number.isFinite(createdAtMs)?Date.now()-createdAtMs:Number.POSITIVE_INFINITY)>ttlSeconds*1e3}function lockOwnerSuffix(info){return info?.owner?` (owner ${info.owner})`:""}const LOCK_WAIT_INITIAL_DELAY_MS=25,LOCK_WAIT_MAX_DELAY_MS=200,LOCK_CONFLICT_RETRY_HINT_MS=250,MAX_STALE_LOCK_REMOVALS=3,STALE_CLEANUP_GATE_SUFFIX=".stale-cleanup",STALE_CLEANUP_GATE_OWNER_FILE="owner.json",STALE_CLEANUP_GATE_STALE_MS=1e4,LOCK_RELEASE_GATE_WAIT_MS=STALE_CLEANUP_GATE_STALE_MS+LOCK_WAIT_MAX_DELAY_MS,STALE_CLEANUP_GATE_MAX_UNVERIFIED_MS=60*6e4;function parseNonNegativeIntegerWaitMs(value){if(typeof value=="string"){const trimmed=value.trim();if(!/^\d+$/.test(trimmed))return;const parsed=Number(trimmed);return Number.isSafeInteger(parsed)?parsed:void 0}if(typeof value=="number"&&Number.isFinite(value)&&value>=0)return Math.trunc(value)}function resolveLockWaitMs(waitMs){const envRaw=process.env.PM_LOCK_WAIT_MS,envParsed=parseNonNegativeIntegerWaitMs(envRaw);if(envParsed!==void 0)return envParsed;const callerParsed=parseNonNegativeIntegerWaitMs(waitMs);return callerParsed!==void 0?callerParsed:0}function sleepWithJitter(baseDelayMs){const jitteredMs=Math.max(1,Math.round(baseDelayMs*(.5+Math.random())));return new Promise(resolve=>setTimeout(resolve,jitteredMs))}function buildLockConflictError(id,info,waitedMs){const waitedSuffix=waitedMs>0?` after waiting ${waitedMs}ms`:"";return new PmCliError(`Item ${id} is locked${lockOwnerSuffix(info)}${waitedSuffix}`,EXIT_CODE.CONFLICT,{code:"lock_conflict",recovery:{retry_after_ms:LOCK_CONFLICT_RETRY_HINT_MS}})}function resolveLockOverrideRelease(result){if(typeof result=="function")return result;if(typeof result=="object"&&result!==null&&"release"in result){const release=result.release;return typeof release=="function"?release:null}return null}function throwIfStaleLockNeedsForce(id,lockInfo,force,forceRequired){if(!force&&forceRequired){const warningSuffix=lockInfo.warnings.length>0?` (${lockInfo.warnings.join(",")})`:"";throw new PmCliError(`Item ${id} lock is stale${warningSuffix}; rerun with --force when supported for this command`,EXIT_CODE.CONFLICT)}}function parseStaleCleanupGateOwner(raw){let parsed;try{parsed=JSON.parse(raw)}catch{return null}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return null;const candidate=parsed,pid=candidate.pid,token=candidate.token,processStartIdentity=candidate.process_start_identity;return typeof pid!="number"||!Number.isInteger(pid)||pid<=0||typeof token!="string"||token.length===0||processStartIdentity!==void 0&&(typeof processStartIdentity!="string"||!/^\d+$/u.test(processStartIdentity))?null:{pid,token,...typeof processStartIdentity=="string"?{process_start_identity:processStartIdentity}:{}}}async function readStaleCleanupGateOwner(gatePath){try{return parseStaleCleanupGateOwner(await fs.readFile(path.join(gatePath,STALE_CLEANUP_GATE_OWNER_FILE),"utf8"))}catch{return null}}function isProcessAlive(pid){if(!Number.isSafeInteger(pid)||pid<=0)return!1;try{return process.kill(pid,0),!0}catch(error){return!isErrno(error,"ESRCH")}}function parseLinuxProcessStartIdentity(raw){const closeParenIndex=raw.lastIndexOf(")");if(closeParenIndex<0)return null;const startTime=raw.slice(closeParenIndex+2).trim().split(/\s+/u)[19];return startTime!==void 0&&/^\d+$/u.test(startTime)?startTime:null}async function readProcessStartIdentity(pid){try{return parseLinuxProcessStartIdentity(await fs.readFile(`/proc/${pid}/stat`,"utf8"))}catch{return null}}async function captureProcessIdentity(pid=process.pid){const processStartIdentity=await readProcessStartIdentity(pid);return{pid,...processStartIdentity===null?{}:{process_start_identity:processStartIdentity}}}async function isProcessIdentityAlive(identity,unverifiedAgeMs,maxUnverifiedAgeMs){if(!isProcessAlive(identity.pid))return!1;const currentStartIdentity=await readProcessStartIdentity(identity.pid);return identity.process_start_identity!==void 0&¤tStartIdentity!==null?currentStartIdentity===identity.process_start_identity:unverifiedAgeMs<=maxUnverifiedAgeMs}async function removeStaleCleanupGateDirectory(gatePath){try{return await fs.rm(gatePath,{recursive:!0,force:!0}),!0}catch{return!1}}async function releaseStaleCleanupGate(gatePath,token){const owner=await readStaleCleanupGateOwner(gatePath);owner===null||owner.token!==token||await removeStaleCleanupGateDirectory(gatePath)}async function tryCreateStaleCleanupGate(gatePath){try{await fs.mkdir(gatePath)}catch(error){return isErrno(error,"EEXIST"),null}const owner={...await captureProcessIdentity(),token:randomUUID()};try{await fs.writeFile(path.join(gatePath,STALE_CLEANUP_GATE_OWNER_FILE),`${JSON.stringify(owner)}
|
|
3
|
-
`,"utf8")}catch{return await removeStaleCleanupGateDirectory(gatePath),null}return owner}async function removeExpiredStaleCleanupGate(gatePath){let gateAgeMs;try{const stats=await fs.stat(gatePath);if(gateAgeMs=Date.now()-stats.mtimeMs,gateAgeMs<=STALE_CLEANUP_GATE_STALE_MS)return!1}catch(error){return isFileMissingError(error)}const owner=await readStaleCleanupGateOwner(gatePath);return owner!==null&&await isProcessIdentityAlive(owner,gateAgeMs,STALE_CLEANUP_GATE_MAX_UNVERIFIED_MS)?!1:removeStaleCleanupGateDirectory(gatePath)}async function acquireStaleCleanupGate(lockPath,_id){const gatePath=`${lockPath}${STALE_CLEANUP_GATE_SUFFIX}`,owner=await tryCreateStaleCleanupGate(gatePath);if(owner!==null)return async()=>releaseStaleCleanupGate(gatePath,owner.token);if(!await removeExpiredStaleCleanupGate(gatePath))return null;const recoveredOwner=await tryCreateStaleCleanupGate(gatePath);return recoveredOwner===null?null:async()=>releaseStaleCleanupGate(gatePath,recoveredOwner.token)}async function removeConfirmedStaleLock(params){const releaseCleanupGate=await acquireStaleCleanupGate(params.lockPath,params.id);if(releaseCleanupGate===null)return{lockInfo:params.fallbackLockInfo,shouldRetryCreate:!1,staleRemovalCounted:!1};try{const currentLockInfo=await readLockInfo(params.lockPath);if(currentLockInfo.info===null&¤tLockInfo.warnings.length===0)return{lockInfo:currentLockInfo,shouldRetryCreate:!0,staleRemovalCounted:!1};if(!isStaleLock(currentLockInfo.info,params.ttlSeconds))return{lockInfo:currentLockInfo,shouldRetryCreate:!1,staleRemovalCounted:!1};if(throwIfStaleLockNeedsForce(params.id,currentLockInfo,params.force,params.forceRequiredForStaleLock),params.staleRemovals>=MAX_STALE_LOCK_REMOVALS)throw buildLockConflictError(params.id,currentLockInfo.info,Date.now()-params.startedAtMs);return{lockInfo:currentLockInfo,shouldRetryCreate:await unlinkLockWithHook(params.lockPath,"lock:stale_remove"),staleRemovalCounted:!0}}finally{await releaseCleanupGate()}}const _testOnly={parseLockInfo,readLockInfo,isErrno,isLockCreateContention,buildLockPayload,isStaleLock,lockOwnerSuffix,resolveLockWaitMs,parseLinuxProcessStartIdentity,readProcessStartIdentity,acquireStaleCleanupGate,removeConfirmedStaleLock};async function acquireLock(pmRoot,id,ttlSeconds,owner,force=!1,forceRequiredForStaleLock=!0,waitMs,options={}){const lockOverride=await runActiveServiceOverride("lock_acquire",{pm_root:pmRoot,id,ttl_seconds:ttlSeconds,owner,force,force_required_for_stale_lock:forceRequiredForStaleLock});if(lockOverride.handled){const release=resolveLockOverrideRelease(lockOverride.result);if(release)return async()=>{await Promise.resolve(release()),await runActiveServiceOverride("lock_release",{pm_root:pmRoot,id,owner})}}const lockPath=getLockPath(pmRoot,id),waitBudgetMs=
|
|
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]="4a6fa947-cc6f-5e48-8722-3db9a1af36f1")}catch{}})();import{isFileMissingError}from"../fs/fs-utils.js";import{constants as fsConstants}from"node:fs";import fs from"node:fs/promises";import path from"node:path";import{randomUUID}from"node:crypto";import{runActiveOnReadHooks,runActiveOnWriteHooks,runActiveServiceOverride}from"../extensions/index.js";import{EXIT_CODE}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{toErrorMessage}from"../shared/primitives.js";import{getLockPath}from"../store/paths.js";import{nowIso}from"../shared/time.js";function parseLockInfo(raw){let parsed;try{parsed=JSON.parse(raw)}catch{return{info:null,warnings:["lock_info_invalid_json"]}}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return{info:null,warnings:["lock_info_invalid_shape"]};const candidate=parsed,id=candidate.id,pid=candidate.pid,owner=candidate.owner,token=candidate.token,createdAt=candidate.created_at,ttlSeconds=candidate.ttl_seconds;return typeof id!="string"||typeof pid!="number"||!Number.isFinite(pid)||typeof owner!="string"||token!==void 0&&(typeof token!="string"||token.trim().length===0)||typeof createdAt!="string"||typeof ttlSeconds!="number"||!Number.isFinite(ttlSeconds)?{info:null,warnings:["lock_info_invalid_shape"]}:{info:{id,pid,owner,...typeof token=="string"?{token}:{},created_at:createdAt,ttl_seconds:ttlSeconds},warnings:[]}}async function readLockInfo(lockPath,emitReadHook=!0){try{const raw=await fs.readFile(lockPath,"utf8");return emitReadHook&&await runActiveOnReadHooks({path:lockPath,scope:"project"}),parseLockInfo(raw)}catch(error){return isFileMissingError(error)?{info:null,warnings:[]}:{info:null,warnings:["lock_info_read_failed"]}}}function isErrno(error,code){return typeof error=="object"&&error!==null&&"code"in error&&error.code===code}async function isLockCreateContention(error,lockPath,platform=process.platform){if(isErrno(error,"EEXIST"))return!0;if(!isErrno(error,"EPERM")&&!isErrno(error,"EACCES")&&!isErrno(error,"EBUSY"))return!1;try{return await fs.lstat(lockPath),!0}catch(probeError){if(platform!=="win32"||!isFileMissingError(probeError)&&!isErrno(probeError,"EPERM")&&!isErrno(probeError,"EACCES")&&!isErrno(probeError,"EBUSY"))return!1}try{return await fs.access(path.dirname(lockPath),fsConstants.W_OK),!0}catch{return!1}}async function emitLockWriteHook(lockPath,op){await runActiveOnWriteHooks({path:lockPath,scope:"project",op})}function buildLockPayload(id,owner,ttlSeconds,token=randomUUID()){return{id,pid:process.pid,owner,token,created_at:nowIso(),ttl_seconds:ttlSeconds}}async function createLockFile(lockPath,id,owner,ttlSeconds,token,createParentDirectories){createParentDirectories&&await fs.mkdir(path.dirname(lockPath),{recursive:!0});const releaseCleanupGate=await acquireStaleCleanupGate(lockPath,id);if(releaseCleanupGate===null)throw await fs.access(path.dirname(lockPath)),Object.assign(new Error("Lock initialization is contended"),{code:"EEXIST"});try{const handle=await fs.open(lockPath,"wx");try{try{await handle.writeFile(`${JSON.stringify(buildLockPayload(id,owner,ttlSeconds,token),null,2)}
|
|
2
|
+
`,"utf8")}finally{await handle.close()}}catch(error){throw await unlinkLockWithHook(lockPath,"lock:release"),error}}finally{await releaseCleanupGate()}await emitLockWriteHook(lockPath,"lock:create")}async function unlinkLockWithHook(lockPath,op){try{return await fs.unlink(lockPath),await emitLockWriteHook(lockPath,op),!0}catch{return!1}}async function releaseOwnedLock(lockPath,id,owner,token){const startedAtMs=Date.now();let backoffMs=LOCK_WAIT_INITIAL_DELAY_MS;for(;;){const releaseCleanupGate=await acquireStaleCleanupGate(lockPath,id);if(releaseCleanupGate!==null){try{const current2=await readLockInfo(lockPath,!1);isOwnedLock(current2.info,id,owner,token)&&await unlinkLockWithHook(lockPath,"lock:release")}finally{await releaseCleanupGate()}return}const current=await readLockInfo(lockPath,!1);if(!isOwnedLock(current.info,id,owner,token))return;const elapsedMs=Date.now()-startedAtMs;if(elapsedMs>=LOCK_RELEASE_GATE_WAIT_MS)return;await sleepWithJitter(Math.min(backoffMs,LOCK_RELEASE_GATE_WAIT_MS-elapsedMs)),backoffMs=Math.min(backoffMs*2,LOCK_WAIT_MAX_DELAY_MS)}}function isOwnedLock(info,id,owner,token){return info?.id===id&&info.pid===process.pid&&info.owner===owner&&info.token===token}function isStaleLock(info,ttlSeconds){const createdAtMs=info?.created_at?Date.parse(info.created_at):Number.NaN;return(Number.isFinite(createdAtMs)?Date.now()-createdAtMs:Number.POSITIVE_INFINITY)>ttlSeconds*1e3}async function hasUnexpiredLockOwner(pmRoot,id,ownerPrefix){const{info}=await readLockInfo(getLockPath(pmRoot,id),!1);return info!==null&&info.owner.startsWith(ownerPrefix)&&!isStaleLock(info,info.ttl_seconds)}function lockOwnerSuffix(info){return info?.owner?` (owner ${info.owner})`:""}const LOCK_WAIT_INITIAL_DELAY_MS=25,LOCK_WAIT_MAX_DELAY_MS=200,LOCK_CONFLICT_RETRY_HINT_MS=250,MAX_STALE_LOCK_REMOVALS=3,STALE_CLEANUP_GATE_SUFFIX=".stale-cleanup",STALE_CLEANUP_GATE_OWNER_FILE="owner.json",STALE_CLEANUP_GATE_STALE_MS=1e4,LOCK_RELEASE_GATE_WAIT_MS=STALE_CLEANUP_GATE_STALE_MS+LOCK_WAIT_MAX_DELAY_MS,STALE_CLEANUP_GATE_MAX_UNVERIFIED_MS=60*6e4;function parseNonNegativeIntegerWaitMs(value){if(typeof value=="string"){const trimmed=value.trim();if(!/^\d+$/.test(trimmed))return;const parsed=Number(trimmed);return Number.isSafeInteger(parsed)?parsed:void 0}if(typeof value=="number"&&Number.isFinite(value)&&value>=0)return Math.trunc(value)}function resolveLockWaitMs(waitMs){const envRaw=process.env.PM_LOCK_WAIT_MS,envParsed=parseNonNegativeIntegerWaitMs(envRaw);if(envParsed!==void 0)return envParsed;const callerParsed=parseNonNegativeIntegerWaitMs(waitMs);return callerParsed!==void 0?callerParsed:0}function cappedLockWaitMs(waitMs,maxWaitMs){return Math.min(resolveLockWaitMs(waitMs),maxWaitMs??1/0)}function sleepWithJitter(baseDelayMs){const jitteredMs=Math.max(1,Math.round(baseDelayMs*(.5+Math.random())));return new Promise(resolve=>setTimeout(resolve,jitteredMs))}function buildLockConflictError(id,info,waitedMs){const waitedSuffix=waitedMs>0?` after waiting ${waitedMs}ms`:"";return new PmCliError(`Item ${id} is locked${lockOwnerSuffix(info)}${waitedSuffix}`,EXIT_CODE.CONFLICT,{code:"lock_conflict",recovery:{retry_after_ms:LOCK_CONFLICT_RETRY_HINT_MS}})}function resolveLockOverrideRelease(result){if(typeof result=="function")return result;if(typeof result=="object"&&result!==null&&"release"in result){const release=result.release;return typeof release=="function"?release:null}return null}function throwIfStaleLockNeedsForce(id,lockInfo,force,forceRequired){if(!force&&forceRequired){const warningSuffix=lockInfo.warnings.length>0?` (${lockInfo.warnings.join(",")})`:"";throw new PmCliError(`Item ${id} lock is stale${warningSuffix}; rerun with --force when supported for this command`,EXIT_CODE.CONFLICT)}}function parseStaleCleanupGateOwner(raw){let parsed;try{parsed=JSON.parse(raw)}catch{return null}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return null;const candidate=parsed,pid=candidate.pid,token=candidate.token,processStartIdentity=candidate.process_start_identity;return typeof pid!="number"||!Number.isInteger(pid)||pid<=0||typeof token!="string"||token.length===0||processStartIdentity!==void 0&&(typeof processStartIdentity!="string"||!/^\d+$/u.test(processStartIdentity))?null:{pid,token,...typeof processStartIdentity=="string"?{process_start_identity:processStartIdentity}:{}}}async function readStaleCleanupGateOwner(gatePath){try{return parseStaleCleanupGateOwner(await fs.readFile(path.join(gatePath,STALE_CLEANUP_GATE_OWNER_FILE),"utf8"))}catch{return null}}function isProcessAlive(pid){if(!Number.isSafeInteger(pid)||pid<=0)return!1;try{return process.kill(pid,0),!0}catch(error){return!isErrno(error,"ESRCH")}}function parseLinuxProcessStartIdentity(raw){const closeParenIndex=raw.lastIndexOf(")");if(closeParenIndex<0)return null;const startTime=raw.slice(closeParenIndex+2).trim().split(/\s+/u)[19];return startTime!==void 0&&/^\d+$/u.test(startTime)?startTime:null}async function readProcessStartIdentity(pid){try{return parseLinuxProcessStartIdentity(await fs.readFile(`/proc/${pid}/stat`,"utf8"))}catch{return null}}async function captureProcessIdentity(pid=process.pid){const processStartIdentity=await readProcessStartIdentity(pid);return{pid,...processStartIdentity===null?{}:{process_start_identity:processStartIdentity}}}async function isProcessIdentityAlive(identity,unverifiedAgeMs,maxUnverifiedAgeMs){if(!isProcessAlive(identity.pid))return!1;const currentStartIdentity=await readProcessStartIdentity(identity.pid);return identity.process_start_identity!==void 0&¤tStartIdentity!==null?currentStartIdentity===identity.process_start_identity:unverifiedAgeMs<=maxUnverifiedAgeMs}async function removeStaleCleanupGateDirectory(gatePath){try{return await fs.rm(gatePath,{recursive:!0,force:!0}),!0}catch{return!1}}async function releaseStaleCleanupGate(gatePath,token){const owner=await readStaleCleanupGateOwner(gatePath);owner===null||owner.token!==token||await removeStaleCleanupGateDirectory(gatePath)}async function tryCreateStaleCleanupGate(gatePath){try{await fs.mkdir(gatePath)}catch(error){return isErrno(error,"EEXIST"),null}const owner={...await captureProcessIdentity(),token:randomUUID()};try{await fs.writeFile(path.join(gatePath,STALE_CLEANUP_GATE_OWNER_FILE),`${JSON.stringify(owner)}
|
|
3
|
+
`,"utf8")}catch{return await removeStaleCleanupGateDirectory(gatePath),null}return owner}async function removeExpiredStaleCleanupGate(gatePath){let gateAgeMs;try{const stats=await fs.stat(gatePath);if(gateAgeMs=Date.now()-stats.mtimeMs,gateAgeMs<=STALE_CLEANUP_GATE_STALE_MS)return!1}catch(error){return isFileMissingError(error)}const owner=await readStaleCleanupGateOwner(gatePath);return owner!==null&&await isProcessIdentityAlive(owner,gateAgeMs,STALE_CLEANUP_GATE_MAX_UNVERIFIED_MS)?!1:removeStaleCleanupGateDirectory(gatePath)}async function acquireStaleCleanupGate(lockPath,_id){const gatePath=`${lockPath}${STALE_CLEANUP_GATE_SUFFIX}`,owner=await tryCreateStaleCleanupGate(gatePath);if(owner!==null)return async()=>releaseStaleCleanupGate(gatePath,owner.token);if(!await removeExpiredStaleCleanupGate(gatePath))return null;const recoveredOwner=await tryCreateStaleCleanupGate(gatePath);return recoveredOwner===null?null:async()=>releaseStaleCleanupGate(gatePath,recoveredOwner.token)}async function removeConfirmedStaleLock(params){const releaseCleanupGate=await acquireStaleCleanupGate(params.lockPath,params.id);if(releaseCleanupGate===null)return{lockInfo:params.fallbackLockInfo,shouldRetryCreate:!1,staleRemovalCounted:!1};try{const currentLockInfo=await readLockInfo(params.lockPath);if(currentLockInfo.info===null&¤tLockInfo.warnings.length===0)return{lockInfo:currentLockInfo,shouldRetryCreate:!0,staleRemovalCounted:!1};if(!isStaleLock(currentLockInfo.info,params.ttlSeconds))return{lockInfo:currentLockInfo,shouldRetryCreate:!1,staleRemovalCounted:!1};if(throwIfStaleLockNeedsForce(params.id,currentLockInfo,params.force,params.forceRequiredForStaleLock),params.staleRemovals>=MAX_STALE_LOCK_REMOVALS)throw buildLockConflictError(params.id,currentLockInfo.info,Date.now()-params.startedAtMs);return{lockInfo:currentLockInfo,shouldRetryCreate:await unlinkLockWithHook(params.lockPath,"lock:stale_remove"),staleRemovalCounted:!0}}finally{await releaseCleanupGate()}}const _testOnly={parseLockInfo,readLockInfo,isErrno,isLockCreateContention,buildLockPayload,isStaleLock,lockOwnerSuffix,resolveLockWaitMs,parseLinuxProcessStartIdentity,readProcessStartIdentity,acquireStaleCleanupGate,removeConfirmedStaleLock};async function acquireLock(pmRoot,id,ttlSeconds,owner,force=!1,forceRequiredForStaleLock=!0,waitMs,options={}){const maxWaitMs=parseNonNegativeIntegerWaitMs(options.maxWaitMs),lockOverride=await runActiveServiceOverride("lock_acquire",{pm_root:pmRoot,id,ttl_seconds:ttlSeconds,owner,force,force_required_for_stale_lock:forceRequiredForStaleLock,...maxWaitMs===void 0?{}:{max_wait_ms:maxWaitMs}});if(lockOverride.handled){const release=resolveLockOverrideRelease(lockOverride.result);if(release)return async()=>{await Promise.resolve(release()),await runActiveServiceOverride("lock_release",{pm_root:pmRoot,id,owner})}}const lockPath=getLockPath(pmRoot,id),waitBudgetMs=cappedLockWaitMs(waitMs,maxWaitMs),startedAtMs=Date.now();let staleRemovals=0,backoffMs=LOCK_WAIT_INITIAL_DELAY_MS;const token=randomUUID();for(;;)try{return await createLockFile(lockPath,id,owner,ttlSeconds,token,options.createParentDirectories!==!1),async()=>{await releaseOwnedLock(lockPath,id,owner,token),await runActiveServiceOverride("lock_release",{pm_root:pmRoot,id,owner})}}catch(error){if(!await isLockCreateContention(error,lockPath))throw new PmCliError(`Failed to acquire lock for ${id}: ${toErrorMessage(error)}`,EXIT_CODE.GENERIC_FAILURE);let lockInfo=await readLockInfo(lockPath);if(isStaleLock(lockInfo.info,ttlSeconds)){const staleRemoval=await removeConfirmedStaleLock({lockPath,id,ttlSeconds,force,forceRequiredForStaleLock,staleRemovals,waitBudgetMs,startedAtMs,fallbackLockInfo:lockInfo});if(lockInfo=staleRemoval.lockInfo,staleRemoval.staleRemovalCounted&&(staleRemovals+=1),staleRemoval.shouldRetryCreate)continue}const elapsedMs=Date.now()-startedAtMs;if(waitBudgetMs===0||elapsedMs>=waitBudgetMs)throw buildLockConflictError(id,lockInfo.info,waitBudgetMs===0?0:elapsedMs);await sleepWithJitter(Math.min(backoffMs,waitBudgetMs-elapsedMs)),backoffMs=Math.min(backoffMs*2,LOCK_WAIT_MAX_DELAY_MS)}}export{_testOnly,acquireLock,captureProcessIdentity,hasUnexpiredLockOwner,isProcessIdentityAlive,readProcessStartIdentity};
|
|
4
4
|
//# sourceMappingURL=lock.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ee7a4cf5-ca04-5ee7-affe-3cc1184e04a0")}catch{}})();import{getActiveCommandContext,runActiveCommandOverride,runActiveRendererOverride,runActiveServiceOverrideSync,setActiveCommandResult}from"../extensions/index.js";import{EXIT_CODE}from"../shared/constants.js";import{isHostOutputSuppressed}from"./output-control.js";import{projectMutationResult}from"./mutation-projection.js";import{attachReadOutputContracts}from"../../sdk/context-intent-contracts.js";import{attachOutputTokenAccounting}from"../../sdk/output-token-accounting.js";import{propagateContextUsageServingReceipt}from"../../sdk/context-usage.js";import{isReadOutputBudgetExceeded,resolveReadOutputEncoding}from"../../sdk/read-output-contracts.js";import{encode as encodeToon}from"@toon-format/toon";import{encodePmTableRows}from"../../sdk/output/table-rows.js";const DECLARED_PROCESS_EXIT_CODES=new Set(Object.values(EXIT_CODE)),COLLECTION_COUNT_ALIASES=new Map([["notes_count","notes"],["tests_count","tests"]]),NATIVE_OUTPUT_MARKER="__pm_native_output";let streamErrorHandlersInstalled=!1;function isPlainObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function setActiveCommandResultOmitted(source){const omitted={read_output:{result_omitted:!0}};propagateContextUsageServingReceipt(source,omitted),setActiveCommandResult(omitted)}function setActiveCommandDeliveryResult(result,receiptSource,structuredDeliveryPreserved){if(structuredDeliveryPreserved){setActiveCommandResult(result);return}setActiveCommandResultOmitted(receiptSource)}function stripNativeOutputMarker(result){if(!isPlainObject(result)||result[NATIVE_OUTPUT_MARKER]!==!0)return result;const{[NATIVE_OUTPUT_MARKER]:_marker,...rest}=result;return rest}function isBrokenPipeError(error){return typeof error=="object"&&error!==null&&error.code==="EPIPE"}function markStdoutBrokenPipeExitCode(){(process.exitCode===void 0||process.exitCode===EXIT_CODE.SUCCESS)&&(process.exitCode=EXIT_CODE.SUCCESS)}function markStderrBrokenPipeExitCode(){(process.exitCode===void 0||process.exitCode===EXIT_CODE.SUCCESS)&&(process.exitCode=EXIT_CODE.GENERIC_FAILURE)}function markBrokenPipeExitCode(target){if(target==="stdout"){markStdoutBrokenPipeExitCode();return}markStderrBrokenPipeExitCode()}function handleUnhandledStreamError(error){const unhandled=error instanceof Error?error:new Error(String(error));setImmediate(()=>{throw unhandled})}function installStreamErrorHandlers(){streamErrorHandlersInstalled||(streamErrorHandlersInstalled=!0,process.stdout.on("error",error=>{if(isBrokenPipeError(error)){markBrokenPipeExitCode("stdout");return}handleUnhandledStreamError(error)}),process.stderr.on("error",error=>{if(isBrokenPipeError(error)){markBrokenPipeExitCode("stderr");return}handleUnhandledStreamError(error)}))}function writeToStream(target,text){installStreamErrorHandlers();try{return target==="stdout"?process.stdout.write(text):process.stderr.write(text),!0}catch(error){if(isBrokenPipeError(error))return markBrokenPipeExitCode(target),!1;throw error}}function writeStdout(text){return writeToStream("stdout",text)}function writeStderr(text){return writeToStream("stderr",text)}function renderScalar(value){return typeof value=="string"?JSON.stringify(value):typeof value=="number"||typeof value=="boolean"?String(value):value===null?"null":JSON.stringify(value)}function tabularObjectArray(value){const keys=Object.keys(value[0]);return keys.length>0&&value.every(entry=>Object.keys(entry).length===keys.length&&keys.every(key=>{if(!Object.hasOwn(entry,key))return!1;const cell=entry[key];return cell===null||typeof cell=="string"||typeof cell=="number"||typeof cell=="boolean"}))}function indentToon(encoded,depth){const indent=" ".repeat(depth);return encoded.split(`
|
|
2
2
|
`).map(line=>`${indent}${line}`).join(`
|
|
3
3
|
`)}function isNestedTableCandidateBounded(rows){const columns=new Set;let presentCells=0;for(const row of rows){const keys=Object.keys(row);presentCells+=keys.length;for(const key of keys)columns.add(key)}return rows.length*columns.size<=presentCells*2}function renderToonObjectEntry(key,entry,depth,allowNestedTable){const indent=" ".repeat(depth);if(!isPlainObject(entry)&&!Array.isArray(entry))return`${indent}${key}: ${renderScalar(entry)}`;if(Array.isArray(entry)){if(entry.length===0)return`${indent}${key}: []`;const expanded=indentToon(encodeToon({[key]:entry}),depth);if(allowNestedTable&&entry.length>=2&&entry.every(isPlainObject)&&!tabularObjectArray(entry)&&isNestedTableCandidateBounded(entry)){const table=encodePmTableRows(entry),tabular=indentToon(encodeToon({[key]:table.rows,[`${key}_encoding`]:table.encoding}),depth);if(Buffer.byteLength(tabular)<Buffer.byteLength(expanded))return tabular}return expanded}return isPlainObject(entry)&&Object.keys(entry).length===0?`${indent}${key}: {}`:`${indent}${key}:
|
|
4
|
-
${renderToonValue(entry,depth+1)}`}function compactToonValue(value,omitDuplicateCountAliases=!0){if(value!=null){if(Array.isArray(value)){const compactedEntries=value.map(entry=>compactToonValue(entry,omitDuplicateCountAliases)).filter(entry=>entry!==void 0);return compactedEntries.length>0?compactedEntries:void 0}if(isPlainObject(value)){const compacted={},entries=Object.entries(value).filter(([key,entry])=>{const canonicalCount=COLLECTION_COUNT_ALIASES.get(key);return!omitDuplicateCountAliases||canonicalCount===void 0||!isPlainObject(value.collection_counts)||entry!==value.collection_counts[canonicalCount]});for(const[key,entry]of entries){if(key==="omitted_field_groups"&&Array.isArray(entry)&&entry.length===0){compacted[key]=[];continue}const compactedEntry=compactToonValue(entry,omitDuplicateCountAliases);compactedEntry!==void 0&&(compacted[key]=compactedEntry)}return Object.keys(compacted).length>0?compacted:void 0}return value}}function renderToonValue(value,depth){const indent=" ".repeat(depth);if(Array.isArray(value))return value.length===0?"[]":indentToon(encodeToon(value),depth);if(isPlainObject(value)){const entries=Object.entries(value);return entries.length===0?"{}":entries.map(([key,entry])=>renderToonObjectEntry(key,entry,depth,!Object.hasOwn(value,`${key}_encoding`))).join(`
|
|
4
|
+
${renderToonValue(entry,depth+1)}`}function compactToonValue(value,omitDuplicateCountAliases=!0){if(value!=null){if(Array.isArray(value)){const compactedEntries=value.map(entry=>compactToonValue(entry,omitDuplicateCountAliases)).filter(entry=>entry!==void 0);return compactedEntries.length>0?compactedEntries:void 0}if(isPlainObject(value)){const compacted={},entries=Object.entries(value).filter(([key,entry])=>{const canonicalCount=COLLECTION_COUNT_ALIASES.get(key);return!omitDuplicateCountAliases||canonicalCount===void 0||!isPlainObject(value.collection_counts)||entry!==value.collection_counts[canonicalCount]});for(const[key,entry]of entries){if(key==="omitted_field_groups"&&Array.isArray(entry)&&entry.length===0){compacted[key]=[];continue}const compactedEntry=compactToonValue(entry,omitDuplicateCountAliases);compactedEntry!==void 0&&(compacted[key]=compactedEntry)}return Object.keys(compacted).length>0?compacted:void 0}return value}}function renderToonValue(value,depth){const indent=" ".repeat(depth);if(Array.isArray(value))return value.length===0?"[]":indentToon(encodeToon(value),depth);if(isPlainObject(value)){const entries=Object.entries(value);return entries.length===0?"{}":entries.map(([key,entry])=>renderToonObjectEntry(key,entry,depth,!Object.hasOwn(value,`${key}_encoding`)&&!(key==="checks"&&isPlainObject(value.verdict)&&value.verdict.authority==="ok"))).join(`
|
|
5
5
|
`)}return`${indent}${renderScalar(value)}`}function renderDefaultMarkdownResult(value){if(!isPlainObject(value)||value.output_default!=="markdown"||typeof value.view!="string"||!Array.isArray(value.events)||!Array.isArray(value.days))return null;const lines=[`# pm calendar (${value.view})`,""],summary=isPlainObject(value.summary)?value.summary:{};if(lines.push(`- events: ${String(summary.events??0)}`),lines.push(""),value.events.length===0)return lines.push("No calendar events matched the selected filters."),`${lines.join(`
|
|
6
6
|
`)}
|
|
7
7
|
`;for(const event of value.events){if(!isPlainObject(event))continue;const kind=typeof event.kind=="string"?event.kind:"event",title=typeof event.item_title=="string"?event.item_title:"",itemId=typeof event.item_id=="string"?event.item_id:"",reminderText=typeof event.reminder_text=="string"&&event.reminder_text.length>0?` ${event.reminder_text}`:"";lines.push(`- [${kind}] ${itemId} ${title}${reminderText}`.trim())}return`${lines.join(`
|
package/dist/core/store/paths.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7f4b8abe-997c-549c-9791-87c78506c8b5")}catch{}})();import{readFileSync,readdirSync,realpathSync,statSync}from"node:fs";import os from"node:os";import path from"node:path";import{PM_DIRNAME,EXIT_CODE,SETTINGS_FILENAME,TYPE_TO_FOLDER}from"../shared/constants.js";import{PmCliError}from"../shared/errors.js";import{isFileAbsentError}from"../fs/fs-utils.js";import{toDefaultFolder}from"../item/type-registry.js";const ITEM_FILE_EXTENSION_BY_FORMAT={json_markdown:".md",toon:".toon"},ITEM_FORMAT_BY_EXTENSION={".md":"json_markdown",".toon":"toon"},NEARBY_TRACKER_SCAN_IGNORED_DIRECTORIES=new Set([".git","coverage","dist","node_modules"]),ITEM_FILE_EXTENSIONS=[".md",".toon"];function pathExists(pathValue){try{return statSync(pathValue),!0}catch{return!1}}function physicalDiscoveryStart(cwd){let ancestor=path.resolve(cwd);const missing=[];for(;path.dirname(ancestor)!==ancestor;)try{return path.join(realpathSync(ancestor),...missing)}catch(error){if(!isFileAbsentError(error))throw error;missing.unshift(path.basename(ancestor)),ancestor=path.dirname(ancestor)}return path.join(realpathSync(ancestor),...missing)}function repositoryBoundaryExists(marker){try{return statSync(marker),!0}catch(error){if(isFileAbsentError(error))return!1;throw error}}function isPmSettingsFile(settingsPath){try{const parsed=JSON.parse(readFileSync(settingsPath,"utf8"));return typeof parsed!="object"||parsed===null||Array.isArray(parsed)?!1:"id_prefix"in parsed||"item_format"in parsed}catch{return!1}}function discoverPmRootFromAncestors(cwd){let current=physicalDiscoveryStart(cwd);for(;;){const candidateRoot=path.join(current,PM_DIRNAME),candidateSettingsPath=path.join(candidateRoot,SETTINGS_FILENAME);if(pathExists(candidateSettingsPath))return candidateRoot;const rootLayoutSettingsPath=path.join(current,SETTINGS_FILENAME);if(pathExists(rootLayoutSettingsPath)&&isPmSettingsFile(rootLayoutSettingsPath))return current;if(repositoryBoundaryExists(path.join(current,".git")))return candidateRoot;const parent=path.dirname(current);if(parent===current)return;current=parent}}function resolveImplicitPmRoot(cwd){return discoverPmRootFromAncestors(cwd)??path.resolve(cwd,PM_DIRNAME)}function discoverNearbyPmRoot(cwd,excludedRoot){const normalizedExcluded=excludedRoot?path.resolve(excludedRoot):void 0;try{return readdirSync(path.resolve(cwd),{withFileTypes:!0}).filter(entry=>entry.isDirectory()&&!NEARBY_TRACKER_SCAN_IGNORED_DIRECTORIES.has(entry.name)).map(entry=>path.join(path.resolve(cwd),entry.name)).filter(candidate=>candidate!==normalizedExcluded).filter(candidate=>pathExists(getSettingsPath(candidate))).filter(candidate=>isPmSettingsFile(getSettingsPath(candidate))).sort((left,right)=>left.localeCompare(right))[0]}catch{return}}function resolvePmRoot(cwd,cliPath){const envPath=process.env.PM_PATH,explicitPath=cliPath?.trim()||envPath?.trim();if(explicitPath){const resolved=path.resolve(cwd,explicitPath);if(!pathExists(getSettingsPath(resolved))){const nestedRoot=path.join(resolved,PM_DIRNAME);if(pathExists(getSettingsPath(nestedRoot)))return nestedRoot}return resolved}return resolveImplicitPmRoot(cwd)}function resolveWorkspaceRoot(pmRoot){const normalizedRoot=path.resolve(pmRoot),parent=path.dirname(normalizedRoot);return path.basename(normalizedRoot)==="pm"&&path.basename(parent)===".agents"?path.dirname(parent):normalizedRoot}function resolveGlobalPmRoot(cwd){const envPath=process.env.PM_GLOBAL_PATH?.trim(),selected=envPath&&envPath.length>0?envPath:path.join(os.homedir(),".pm-cli");return path.resolve(cwd,selected)}function getSettingsPath(pmRoot){return path.join(pmRoot,SETTINGS_FILENAME)}function getTypeDirPath(pmRoot,type,typeToFolder=TYPE_TO_FOLDER){const folder=typeToFolder[type]??toDefaultFolder(type);return path.join(pmRoot,folder)}function getItemPath(pmRoot,type,id,itemFormat="toon",typeToFolder=TYPE_TO_FOLDER){return path.join(getTypeDirPath(pmRoot,type,typeToFolder),`${id}${ITEM_FILE_EXTENSION_BY_FORMAT[itemFormat]}`)}function getItemFormatFromPath(itemPath){const normalizedItemPath=itemPath.replaceAll("\\","/"),extension=path.posix.extname(normalizedItemPath).toLowerCase();return ITEM_FORMAT_BY_EXTENSION[extension]??null}function getHistoryPath(pmRoot,id){if(!/^(?!\.{1,2}$)[^/\\:\0]+$/.test(id))throw new PmCliError("Invalid history item id: expected a single filename.",EXIT_CODE.USAGE);return path.join(pmRoot,"history",`${id}.jsonl`)}function getLockPath(pmRoot,id){return path.join(pmRoot,"locks",`${id}.lock`)}function getRuntimePath(pmRoot){return path.join(pmRoot,"runtime")}function getTestRunsPath(pmRoot){return path.join(getRuntimePath(pmRoot),"test-runs")}function getTestRunsRecordsPath(pmRoot){return path.join(getTestRunsPath(pmRoot),"runs")}function getTestRunRecordPath(pmRoot,runId){return path.join(getTestRunsRecordsPath(pmRoot),`${runId}.json`)}function getTestRunsStdoutPath(pmRoot){return path.join(getTestRunsPath(pmRoot),"stdout")}function getTestRunsStderrPath(pmRoot){return path.join(getTestRunsPath(pmRoot),"stderr")}function getTestRunStdoutPath(pmRoot,runId){return path.join(getTestRunsStdoutPath(pmRoot),`${runId}.log`)}function getTestRunStderrPath(pmRoot,runId){return path.join(getTestRunsStderrPath(pmRoot),`${runId}.log`)}function getTestRunsResultsPath(pmRoot){return path.join(getTestRunsPath(pmRoot),"results")}function getTestRunResultPath(pmRoot,runId){return path.join(getTestRunsResultsPath(pmRoot),`${runId}.json`)}export{ITEM_FILE_EXTENSIONS,ITEM_FILE_EXTENSION_BY_FORMAT,discoverNearbyPmRoot,getHistoryPath,getItemFormatFromPath,getItemPath,getLockPath,getRuntimePath,getSettingsPath,getTestRunRecordPath,getTestRunResultPath,getTestRunStderrPath,getTestRunStdoutPath,getTestRunsPath,getTestRunsRecordsPath,getTestRunsResultsPath,getTestRunsStderrPath,getTestRunsStdoutPath,getTypeDirPath,resolveGlobalPmRoot,resolveImplicitPmRoot,resolvePmRoot,resolveWorkspaceRoot};
|
|
2
2
|
//# sourceMappingURL=paths.js.map
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Supported explicit classifications for intentional telemetry delivery. */
|
|
2
2
|
export declare const PM_TELEMETRY_SOURCE_CONTEXT_VALUES:readonly ["user","automation","test","dogfood"];
|
|
3
|
+
/** Share native and package test signals across consent, attribution and flush lifetime. */
|
|
4
|
+
export declare function isTelemetryTestEnvironment(env?:Readonly<Record<string,string | undefined>>):boolean;
|
|
3
5
|
/** Fixed core reads eligible only after runtime ownership has been established. */
|
|
4
6
|
export declare const TELEMETRY_SAMPLEABLE_READS:ReadonlySet<string>;
|
|
5
7
|
/** Resolve explicit read sampling only for core-only invocations with no write-capable extensions. */
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
1
|
+
(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="eae1b641-d6ed-5c32-899e-fe534a17aafd")}catch{}})();const TRUE_VALUES=new Set(["1","true","yes","on"]),PM_TELEMETRY_SOURCE_CONTEXT_VALUES=["user","automation","test","dogfood"],SOURCE_CONTEXTS=new Set(PM_TELEMETRY_SOURCE_CONTEXT_VALUES);function isTelemetryTestEnvironment(env=process.env){return typeof env.VITEST=="string"||typeof env.VITEST_WORKER_ID=="string"||typeof env.NODE_TEST_CONTEXT=="string"||(env.NODE_ENV??"").trim().toLowerCase()==="test"}const TELEMETRY_SAMPLEABLE_READS=new Set(["stats","ops stats","list","get","next","context","activity","aggregate"]);function resolveTelemetryReadSampleRate(command,noExtensions,env=process.env){const raw=env.PM_TELEMETRY_READ_SAMPLE_RATE?.trim();if(!raw||!noExtensions||!TELEMETRY_SAMPLEABLE_READS.has(command))return 1;const rate=Number(raw);return Number.isFinite(rate)&&rate>0&&rate<=1?rate:1}function telemetryEnvironmentFlag(key,env){return TRUE_VALUES.has((env[key]??"").trim().toLowerCase())}function resolveTelemetryEnvironmentPolicy(env=process.env){const doNotTrack=telemetryEnvironmentFlag("DO_NOT_TRACK",env),override=(env.PM_TELEMETRY_SOURCE_CONTEXT??"").trim().toLowerCase(),testSuppressed=isTelemetryTestEnvironment(env)&&!SOURCE_CONTEXTS.has(override)&&!telemetryEnvironmentFlag("PM_TELEMETRY_SEND_TEST_EVENTS",env);return{telemetry_disabled:doNotTrack||testSuppressed||telemetryEnvironmentFlag("PM_TELEMETRY_DISABLED",env)||telemetryEnvironmentFlag("PM_NO_TELEMETRY",env),do_not_track:doNotTrack,test_suppressed:testSuppressed}}export{PM_TELEMETRY_SOURCE_CONTEXT_VALUES,TELEMETRY_SAMPLEABLE_READS,isTelemetryTestEnvironment,resolveTelemetryEnvironmentPolicy,resolveTelemetryReadSampleRate};
|
|
2
2
|
//# sourceMappingURL=policy.js.map
|
|
@@ -161,6 +161,7 @@ declare function runtimeStatePath(globalPmRoot:string):string;
|
|
|
161
161
|
declare function flushLockPath(globalPmRoot:string):string;
|
|
162
162
|
declare function flushSpawnLockPath(globalPmRoot:string):string;
|
|
163
163
|
declare function telemetryFlushRunnerPath():string;
|
|
164
|
+
/** Select foreground lifetime from explicit worker flags or a recognized test environment. */
|
|
164
165
|
declare function shouldFlushInline():boolean;
|
|
165
166
|
declare function readRuntimeState(globalPmRoot:string):Promise<TelemetryRuntimeState>;
|
|
166
167
|
declare function writeRuntimeState(globalPmRoot:string,patch:TelemetryRuntimeState):Promise<void>;
|
|
@@ -322,7 +323,7 @@ next_attempt_after:string;
|
|
|
322
323
|
}>):Promise<number>;
|
|
323
324
|
/** POST due spans outside the mutation mutex, then reconcile successes and retry metadata against the current queue; publish export diagnostics for health inspection. */
|
|
324
325
|
declare function flushPendingOtelSpans(globalPmRoot:string,retentionDays:number):Promise<void>;
|
|
325
|
-
/** Flush
|
|
326
|
+
/** Flush event and OTLP queues together for a detached worker or inline test delivery, isolating each artifact's failures for a later retry. */
|
|
326
327
|
declare function flushTelemetryArtifacts(globalPmRoot:string,endpoint:string,retentionDays:number):Promise<void>;
|
|
327
328
|
export { withQueueMutation as withTelemetryQueueMutation };
|
|
328
329
|
/** Serialize complete queue transactions across processes. The per-acquisition wait defaults to five seconds for maintenance; foreground capture supplies a shorter budget. PM_LOCK_WAIT_MS remains an explicit override. Never hold the lock during network I/O. */
|
|
@@ -409,12 +410,13 @@ runtimeStatePath:typeof runtimeStatePath;
|
|
|
409
410
|
writeRuntimeState:typeof writeRuntimeState;
|
|
410
411
|
};
|
|
411
412
|
declare function flushQueueWithProcessLock(globalPmRoot:string,endpoint:string,retentionDays:number):Promise<boolean>;
|
|
412
|
-
|
|
413
|
+
/** Serialize foreground snapshots or dispatch one detached worker for queued production delivery. */
|
|
414
|
+
declare function scheduleTelemetryFlush(globalPmRoot:string,endpoint:string,retentionDays:number):Promise<void> | undefined;
|
|
413
415
|
/** Drain consented event and span queues without reviving removed storage in detached workers. Foreground SDK callers retain identity initialization; workers only read existing base settings and never scaffold directories, schemas or identities. */
|
|
414
416
|
export declare function flushTelemetryQueueNow(globalPmRoot?:string):Promise<void>;
|
|
415
417
|
/** Atomically validate consent, initialize identity, and capture an invocation; defer sampled reads until their outcome determines pair retention and schedule delivery after releasing the mutex. */
|
|
416
418
|
export declare function startTelemetryCommand(context:TelemetryCommandContext):Promise<ActiveTelemetryCommand | null>;
|
|
417
|
-
/** Complete an invocation only while
|
|
419
|
+
/** Complete an invocation only while consent and installation identity agree; retain failed reads, weight selected pairs and await delivery in inline mode. */
|
|
418
420
|
export declare function finishTelemetryCommand(activeCommand:ActiveTelemetryCommand | null,outcome:TelemetryCommandOutcome):Promise<void>;
|
|
419
421
|
/** Atomically validate consent and append a sanitized command error with its installation identity; schedule delivery only after releasing the queue mutex. */
|
|
420
422
|
export declare function emitTelemetryErrorEvent(context:TelemetryErrorEventContext):Promise<void>;
|