@unbrained/pm-cli 2026.9.19 → 2026.9.21
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 +2 -2
- package/CHANGELOG.md +954 -924
- package/dist/cli/main.d.ts +10 -76
- package/dist/cli/main.js +1 -2
- package/dist/cli/register-operations.js +1 -1
- package/dist/cli/runtime/activation.d.ts +51 -0
- package/dist/cli/runtime/activation.js +2 -0
- package/dist/cli/runtime/invocation-options.d.ts +41 -0
- package/dist/cli/runtime/invocation-options.js +2 -0
- package/dist/cli/runtime/selection.d.ts +29 -0
- package/dist/cli/runtime/selection.js +2 -0
- package/dist/cli/runtime/telemetry-outcome.d.ts +20 -0
- package/dist/cli/runtime/telemetry-outcome.js +2 -0
- package/dist/cli-bundle/bundle-manifest.json +150 -150
- package/dist/cli-bundle/chunks/{chunk-QA4GUEKJ.js → chunk-2QLXN6HZ.js} +46 -46
- package/dist/cli-bundle/chunks/chunk-2UNYUB4A.js +2 -0
- package/dist/cli-bundle/chunks/chunk-4SI67A2F.js +8 -0
- package/dist/cli-bundle/chunks/chunk-7YUYLYJQ.js +6 -0
- package/dist/cli-bundle/chunks/{chunk-7CN53F4S.js → chunk-FBWAECBI.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-GRHSNUQO.js +20 -0
- package/dist/cli-bundle/chunks/chunk-HAFSMFJK.js +3 -0
- package/dist/cli-bundle/chunks/chunk-JBJUOOJI.js +238 -0
- package/dist/cli-bundle/chunks/chunk-K7RWRJLT.js +29 -0
- package/dist/cli-bundle/chunks/chunk-NHRB3L5T.js +2 -0
- package/dist/cli-bundle/chunks/{chunk-CCLWCESZ.js → chunk-QZTS23BV.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-K4VAU4HU.js → chunk-SDLBF4PY.js} +1252 -1252
- package/dist/cli-bundle/chunks/{register-list-query-RMZNHSII.js → register-list-query-5V43MYPN.js} +6 -6
- package/dist/cli-bundle/chunks/{register-mutation-HJGSGX3H.js → register-mutation-DXES37MA.js} +4 -4
- package/dist/cli-bundle/chunks/register-operations-LJU5H2CU.js +2 -0
- package/dist/cli-bundle/chunks/register-setup-HJUNGYBB.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-3XPBKIV6.js +12 -0
- package/dist/cli-bundle/focused-chunks/{chunk-7Y7PAC56.js → chunk-5BLRMUMK.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-5SZ4JSPZ.js → chunk-6MNKQKT6.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-IKPR4VVN.js → chunk-DPBTIFW7.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-J3GN4SQT.js → chunk-DRNXMOSV.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-P4BA7OX7.js → chunk-FXAZPSU6.js} +7 -7
- package/dist/cli-bundle/focused-chunks/{chunk-ARK4FIO4.js → chunk-HYPK5OPA.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-I4WDON3K.js → chunk-IA5CCSBB.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-CJ4QA4RW.js → chunk-ISEOBALS.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-ZI2YBJFH.js → chunk-K5ZCBC6Y.js} +3 -3
- package/dist/cli-bundle/focused-chunks/{chunk-V3YMNAO7.js → chunk-L6L4XCLY.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TDHVROGL.js → chunk-N6KI3LWF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-PC6ZZVNP.js +20 -0
- package/dist/cli-bundle/focused-chunks/chunk-RQL5WLNZ.js +30 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZDBKYZFE.js → chunk-U2SB2BMM.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-YDFEWXXZ.js → chunk-UIS5FVHH.js} +53 -53
- package/dist/cli-bundle/main.js +26 -27
- 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 +39 -39
- 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 +42 -42
- 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 +8 -8
- package/dist/core/diagnostics/remediation.js +1 -1
- package/dist/core/extensions/extension-types.d.ts +2 -2
- package/dist/core/extensions/loader.d.ts +9 -15
- package/dist/core/extensions/loader.js +1 -1
- package/dist/core/extensions/manifest-parser.d.ts +5 -0
- package/dist/core/extensions/manifest-parser.js +2 -0
- package/dist/core/extensions/registration-contracts.d.ts +34 -0
- package/dist/core/extensions/registration-contracts.js +2 -0
- package/dist/core/governance/issue-codes.d.ts +10 -1
- package/dist/core/governance/issue-codes.js +1 -1
- package/dist/core/validate/fix-planning.d.ts +3 -3
- package/dist/core/validate/fix-planning.js +1 -1
- package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
- package/dist/sdk/completion/bash.d.ts +3 -0
- package/dist/sdk/completion/bash.js +2 -0
- package/dist/sdk/completion/fish.d.ts +3 -0
- package/dist/sdk/completion/fish.js +1054 -0
- package/dist/sdk/completion/shared.d.ts +103 -0
- package/dist/sdk/completion/shared.js +2 -0
- package/dist/sdk/completion/zsh.d.ts +3 -0
- package/dist/sdk/completion/zsh.js +1109 -0
- package/dist/sdk/completion.d.ts +5 -30
- package/dist/sdk/completion.js +1 -2160
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
- package/dist/sdk/governance/closure-timestamps.d.ts +32 -0
- package/dist/sdk/governance/closure-timestamps.js +2 -0
- package/dist/sdk/governance/validate-normalization.d.ts +2 -0
- package/dist/sdk/governance/validate-normalization.js +1 -1
- package/dist/sdk/governance/validate.js +1 -1
- package/dist/sdk/governance.d.ts +1 -0
- package/dist/sdk/governance.js +1 -1
- package/dist/sdk/public-surface.json +1 -1
- package/dist/sdk/query/search/corpus.d.ts +27 -0
- package/dist/sdk/query/search/corpus.js +2 -0
- package/dist/sdk/query/search/filters.d.ts +27 -0
- package/dist/sdk/query/search/filters.js +2 -0
- package/dist/sdk/query/search/input.d.ts +28 -0
- package/dist/sdk/query/search/input.js +2 -0
- package/dist/sdk/query/search/lexical.d.ts +34 -0
- package/dist/sdk/query/search/lexical.js +2 -0
- package/dist/sdk/query/search/response.d.ts +34 -0
- package/dist/sdk/query/search/response.js +2 -0
- package/dist/sdk/query/search/semantic.d.ts +229 -0
- package/dist/sdk/query/search/semantic.js +3 -0
- package/dist/sdk/query/search/types.d.ts +123 -0
- package/dist/sdk/query/search/types.js +2 -0
- package/dist/sdk/query/search.d.ts +13 -364
- package/dist/sdk/query/search.js +1 -2
- package/dist/sdk/runtime/actions.d.ts +4 -0
- package/dist/sdk/runtime/actions.js +2 -0
- package/dist/sdk/runtime/context.d.ts +38 -0
- package/dist/sdk/runtime/context.js +2 -0
- package/dist/sdk/runtime/schema.d.ts +4 -0
- package/dist/sdk/runtime/schema.js +2 -0
- package/dist/sdk/runtime.d.ts +90 -95
- package/dist/sdk/runtime.js +1 -1
- package/docs/ARCHITECTURE.md +68 -0
- package/docs/HISTORY_GOVERNANCE_REPAIR.md +66 -0
- package/docs/README.md +2 -0
- package/docs/VALIDATION_PORTABILITY.md +82 -0
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
- package/marketplace.json +2 -2
- package/package.json +6 -6
- 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/extensions/guide-shell/runtime.ts +23 -17
- 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-codex/.codex-plugin/plugin.json +1 -1
- package/dist/cli-bundle/chunks/chunk-AACGU5IA.js +0 -3
- package/dist/cli-bundle/chunks/chunk-J7NP7QLW.js +0 -6
- package/dist/cli-bundle/chunks/chunk-KHN4NMKT.js +0 -238
- package/dist/cli-bundle/chunks/chunk-KYG2QKNY.js +0 -29
- package/dist/cli-bundle/chunks/chunk-OQS2Y6VN.js +0 -2
- package/dist/cli-bundle/chunks/chunk-QTHR3LXF.js +0 -20
- package/dist/cli-bundle/chunks/chunk-RVMDPIGD.js +0 -2
- package/dist/cli-bundle/chunks/chunk-WASMH647.js +0 -8
- package/dist/cli-bundle/chunks/register-operations-LBEMFUMM.js +0 -2
- package/dist/cli-bundle/chunks/register-setup-MU557JAA.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-I32L3FWW.js +0 -12
- package/dist/cli-bundle/focused-chunks/chunk-OOZHQFBF.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-QL4MO5M2.js +0 -30
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4883f097-fa29-5b45-9d50-94e987465a0e")}catch(e2){}})();const REMEDIATION_REGISTRY=Object.freeze([{code:"missing_directory",command:"pm init",summary:"Recreate missing tracker directories (pm init is idempotent and restores the scaffold)."},{code:"settings_read_fs_error",command:"pm config list --json",summary:"settings.json could not be read as a regular file and pm fell back to defaults; repair the reported path or permissions, then re-run."},{code:"settings_read_invalid_json",command:"pm config list --json",summary:"settings.json is not valid JSON and pm fell back to defaults; fix the syntax error in the reported path, then re-run."},{code:"settings_read_invalid_schema",command:"pm config list --json",summary:"settings.json failed schema validation and pm fell back to defaults; correct the reported key in the file, then re-run."},{code:"settings_read_merge_failed",command:"pm config list --json",summary:"Global/project settings could not be merged; reconcile the conflicting keys in the reported settings files."},{code:"settings:id_prefix_empty",command:"pm config list --json",summary:'id_prefix is empty; set a non-empty "id_prefix" in settings.json so generated item ids are well-formed.'},{code:"settings:locks_ttl_non_positive",command:"pm config list --json",summary:'locks.ttl_seconds must be positive; set a positive "locks.ttl_seconds" in settings.json.'},{code:"telemetry_state_invalid_json",command:"pm health --check-telemetry",summary:"Local telemetry state file is corrupt; pm recreates it on the next flush. Advisory only."},{code:"telemetry_queue_invalid_rows",command:"pm health --check-telemetry",summary:"The telemetry queue has unparseable rows; they are skipped on the next flush. Advisory only."},{code:"telemetry_queue_pending",command:"pm health --check-telemetry",summary:"Telemetry events are queued; they flush automatically on the next reachable command. Advisory only."},{code:"telemetry_queue_high_retries",command:"pm telemetry flush",summary:"Some queued telemetry events are near retry exhaustion; flush now and verify endpoint reachability before entries are dropped."},{code:"telemetry_endpoint_probe_failed",command:"pm health --check-telemetry",summary:"The telemetry endpoint is unreachable; events stay queued until it recovers. Advisory only."},{code:"telemetry_endpoint_probe_http_status",command:"pm health --check-telemetry",summary:"The telemetry endpoint returned a non-success status; events stay queued until it recovers. Advisory only."},{code:"telemetry_schema_version_behind",command:"pm health --check-telemetry",summary:"Client schema is behind server; upgrade pm-cli to emit the latest event shape."},{code:"telemetry_otel_export_failing",command:"pm health --check-telemetry",summary:"OTLP trace spans are queued but the traces endpoint export is failing; spans retry automatically on the next reachable command, or set PM_TELEMETRY_OTEL_DISABLED=1 to skip OTLP export. Advisory only."},{code:"merge_driver_configuration_missing",command:"pm merge install",summary:"Install the clone-local Git drivers required by the tracker merge fence."},{code:"merge_driver_configuration_drift",command:"pm merge install",summary:"Reinstall clone-local Git drivers after runtime or package paths change."},{code:"validate_merge_driver_configuration",command:"pm merge install",summary:"Restore missing or drifted clone-local Git merge driver commands."},{code:"integrity_item_unreadable",command:"pm validate --check-files --verbose-diagnostics",summary:"An item file could not be read; restore or repair the file at the reported path."},{code:"integrity_item_parse_failed",command:"pm validate --check-files --verbose-diagnostics",summary:"An item file failed to parse; fix the malformed item metadata at the reported path."},{code:"integrity_item_conflict_marker",command:"pm validate --check-files --verbose-diagnostics",summary:"An item file contains Git conflict markers; resolve the <<<<<<< / >>>>>>> markers at the reported line."},{code:"integrity_history_unreadable",command:"pm history-repair <id>",summary:"A history stream could not be read; re-anchor the affected item's history chain."},{code:"integrity_history_invalid_json",command:"pm history-repair <id>",summary:"A history stream contains invalid JSON; re-anchor the affected item's history chain."},{code:"integrity_history_conflict_marker",command:"pm history-repair <id>",summary:"A history stream contains Git conflict markers; resolve the markers, then re-anchor the chain."},{code:"validate_storage_unreadable_items",command:"pm validate --check-storage-integrity --verbose-diagnostics",summary:"An on-disk item file cannot be parsed (for example a botched merge resolution with stale TOON count headers); repair or restore the file at the reported path \u2014 list commands silently skip it while pm get hard-errors."},{code:"validate_storage_duplicate_item_ids",command:"pm validate --check-storage-integrity --verbose-diagnostics",summary:"One item id is claimed by multiple item documents \u2014 usually two branches minting the same id for different items before merging (GH-600). Keep one document, recreate the other item under a fresh id (pm copy, then delete the colliding file), and consider raising ids.token_length for concurrent multi-agent work."},{code:"validate_storage_history_conflict_markers",command:"pm merge driver history <base> <ours> <theirs>",summary:"A history stream contains unresolved Git conflict markers; re-merge it with the pm history merge driver (or resolve the markers by hand), then run pm history-repair for the item."},{code:"validate_storage_unparseable_history",command:"pm history-repair <id>",summary:"A history stream's newest line is not valid JSONL; repair or restore the stream before further mutations."},{code:"validate_storage_resurrected_items",command:"pm delete <id>",summary:"A live item's newest history operation is a delete: a delete/modify merge silently resurrected it. Decide the winner \u2014 re-delete the item, or keep it and append a mutation documenting the revival."},{code:"validate_storage_unparseable_config",command:"pm merge driver json <base> <ours> <theirs>",summary:"settings.json or a schema file cannot be parsed, so pm silently falls back to defaults; re-merge it with the pm JSON merge driver or fix the file by hand, then rerun pm validate."},{code:"validate_merge_fence_drift",command:"pm merge install",summary:"The committed .gitattributes merge fence no longer matches the active schema's type folders or tracker JSONL stores; rerun pm merge install (and commit .gitattributes) so every tracker artifact keeps its field-aware merge driver."},{code:"validate_storage_tracked_runtime_cache_files",command:"git rm --cached -r -- <tracked-runtime-directories>",summary:"Clone-local tracker runtime artifacts are committed. Run the exact tracked_runtime_cache.remediation_command, commit the index-only removals and managed .gitignore fence, then rerun validation."},{code:"integrity_item_outdated_format_version",command:"pm validate --verbose-diagnostics",summary:"An item predates the current storage format version; a pm storage migration rewrites it. Use --verbose-diagnostics to list the affected items."},{code:"integrity_item_ahead_format_version",command:"npm install -g @unbrained/pm-cli@latest",summary:"An item was written by a newer pm format version than this runtime supports; upgrade pm to read and validate it safely."},{code:"tracked_runtime_cache_files",command:"git rm --cached -r -- <tracked-runtime-directories>",summary:"Clone-local tracker runtime artifacts are committed. Run the exact tracked_runtime_cache.remediation_command from the integrity check, commit the index-only removals, and keep the managed .gitignore fence."},{code:"merge_decisions_unreviewed",command:"pm merge reconcile --dry-run",summary:"Review the pending merge receipts, re-apply any intended discarded values, then run pm merge reconcile; lossy receipts require explicit --force acceptance."},{code:"merge_receipts_pending",command:"pm merge reconcile",summary:"A lossless merge receipt is still pending; run pm merge reconcile to settle it (optionally preview first with --dry-run) so a green health gate certifies receipt settlement, not only intact data."},{code:"merge_receipt_evidence_invalid",command:"pm merge report --include-reconciled --json",summary:"One or more receipt candidates failed bounded-file, schema, identity, or copy-consistency validation; inspect the report's privacy-safe source, receipt id, and reason before repairing only the named evidence."},{code:"merge_receipt_history_reference_missing",command:"pm merge reconcile --dry-run",summary:"Review the bounded coordinates and recover available evidence first; for exact pre-durable clone-local-only references, rerun with --force so pm appends an audited disposition and proves the health finding is cleared without rewriting history."},{code:"validate_merge_decisions_unreviewed",command:"pm merge reconcile --dry-run",summary:"Review the pending merge receipts before reconciliation; history-repair alone does not settle them, and lossy receipts require explicit --force acceptance."},{code:"history_drift_missing_stream",command:"pm history-repair <id>",summary:"The item has no history stream; re-anchor the chain to rebuild it (pm history-repair --all repairs every drifted stream in one pass)."},{code:"history_drift_unreadable_stream",command:"pm history-repair <id>",summary:"The item's history stream is unreadable; re-anchor the chain (pm history-repair --all repairs every drifted stream in one pass)."},{code:"history_drift_hash_mismatch",command:"pm history-repair <id>",summary:"The item's content hash no longer matches its history; re-anchor the chain (pm history-repair --all repairs every drifted stream in one pass)."},{code:"history_drift_chain_mismatch",command:"pm history-repair <id>",summary:"The item's history chain is broken; re-anchor the chain (pm history-repair --all repairs every drifted stream in one pass)."},{code:"history_drift_version_skew",command:"npm install -g @unbrained/pm-cli@latest",summary:"A history stream declares an item hash version this runtime does not support; upgrade pm to verify the chain instead of re-anchoring it."},{code:"history_drift_merge_receipt",command:"pm merge reconcile",summary:"Canonical path, changed-field, and merged-value hash evidence attributes this drift to a pending receipt; run reconciliation (optionally preview first with --dry-run) instead of repairing history directly."},{code:"history_stream_over_compact_threshold",command:"pm history-compact <id>",summary:"The history stream exceeds the configured compaction threshold; compact it (pm history-compact --all-streams sweeps every over-threshold stream in one pass)."},{code:"history_unknown_author_events",command:'pm history-author-acknowledge --all-actionable --attributed-author "<principal>" --reviewer "<reviewer>" --reason "<evidence>"',summary:"Review the actionable coordinates, then record an append-only attribution disposition for the complete current set."},{code:"provenance_value_domain_invalid",command:"pm history-repair --all --normalize-provenance",summary:"Remove invalid bounded provenance observations from affected streams and append privacy-safe aggregate repair receipts."},{code:"validate_history_unknown_author_events",command:'pm history-author-acknowledge --all-actionable --attributed-author "<principal>" --reviewer "<reviewer>" --reason "<evidence>"',summary:"Review the actionable coordinates, then record an append-only attribution disposition for the complete current set."},{code:"locks_stale_count",command:"pm gc --scope locks",summary:"Stale item-claim locks (embedded ttl elapsed) can block mutations; sweep them \u2014 gc retains active and unparseable locks."},{code:"locks_unreadable",command:"pm gc --scope locks --dry-run",summary:"Some lock files could not be read; preview the sweep and inspect the unreadable files manually \u2014 gc never deletes what it cannot read."},{code:"extension_update_health_partial_coverage",command:"pm extension --adopt-all --project",summary:"Update-health coverage is partial because unmanaged extensions were skipped; adopt the existing installs into managed metadata so the update scan covers them (use --global for global-scope extensions, or pm package --adopt-all when working with packages)."},{code:"vectorization_stale_items_remaining",command:"pm health --refresh-vectors",summary:"Some items have stale embeddings; refresh vectors so semantic search results stay current."},{code:"vectorization_embedding_identity_changed",command:"pm reindex --mode semantic",summary:"Embedding provider/model changed since the last index; run a semantic reindex to rebuild vectors."},{code:"validate_metadata_missing_acceptance_criteria",command:'pm update <id> --acceptance-criteria "<criteria>"',summary:"Backfill the missing acceptance criteria on the reported item(s)."},{code:"validate_metadata_missing_estimate",command:'pm update <id> --estimate "<estimate>"',summary:"Backfill the missing estimate on the reported item(s)."},{code:"validate_metadata_missing_close_reason",command:'pm update <id> --close-reason "<reason>"',summary:"Backfill the missing close reason on the reported closed item(s)."},{code:"validate_metadata_missing_reviewer",command:'pm update <id> --reviewer "<name>"',summary:"Backfill the missing reviewer on the reported item(s)."},{code:"validate_metadata_missing_risk",command:'pm update <id> --risk "<level>"',summary:"Backfill the missing risk on the reported item(s)."},{code:"validate_metadata_missing_confidence",command:'pm update <id> --confidence "<level>"',summary:"Backfill the missing confidence on the reported item(s)."},{code:"validate_metadata_missing_sprint",command:'pm update <id> --sprint "<sprint>"',summary:"Backfill the missing sprint on the reported item(s)."},{code:"validate_metadata_missing_release",command:'pm update <id> --release "<release>"',summary:"Backfill the missing release on the reported item(s)."},{code:"validate_metadata_custom_profile_missing_required_fields",command:'pm config set metadata-required-fields --criterion "<field>"',summary:"Config-driven finding: the custom metadata profile has no required fields configured and falls back to core, so configure the fields rather than mutating items."},{code:"validate_metadata_duplicate_issue_codes",command:'pm update <id> --title "<distinct title>"',summary:"Two or more items share one logical issue code (GH-235); give each a distinct title so the derived code is unique, or close the redundant item with pm close <id> --duplicate-of <canonical-id> (closed-as-duplicate items are excluded from the check)."},{code:"validate_resolution_missing_fields",command:'pm update <id> --resolution "<how resolved>"',summary:"Backfill resolution / expected_result / actual_result on the reported closed item(s)."},{code:"validate_lifecycle_active_closure_like_metadata",command:"pm update <id> --unset <closure-like-field>",summary:"Clear the closure-like field the validator flags on this active item \u2014 the detail row names it (resolution / actual-result / blocked-reason) \u2014 or close the item if it is actually done."},{code:"validate_lifecycle_active_terminal_parent",command:"pm update <id> --parent <active-parent-id>",summary:"Reopen the terminal parent or move the active child under a non-terminal parent."},{code:"validate_lifecycle_stale_blockers",command:"pm update <id> --unset blocked-by --unset blocked-reason",summary:"Resolve the stale blocker the validator flags: clear blocked-by/blocked-reason when they linger on a non-blocked item or report a resolved blocker; if instead a blocked item is missing blocker context, add the context or move it out of a blocked status."},{code:"validate_lifecycle_dependency_cycles_error",command:"pm update <id> --dep-remove <dep-id>",summary:"Break the dependency cycle by removing one edge from the reported cycle."},{code:"validate_lifecycle_dependency_cycles",command:"pm update <id> --dep-remove <dep-id>",summary:"Break the dependency cycle by removing one edge from the reported cycle."},{code:"validate_hierarchy_parent_cycle_error",command:"pm update <id> --parent <other-id>",summary:"Break the parent-hierarchy cycle by reparenting one item in the reported cycle to a non-cyclic parent (or clear it with pm update <id> --unset parent)."},{code:"validate_hierarchy_parent_cycle",command:"pm update <id> --parent <other-id>",summary:"Break the parent-hierarchy cycle by reparenting one item in the reported cycle to a non-cyclic parent (or clear it with pm update <id> --unset parent)."},{code:"validate_files_missing_linked_paths",command:"pm <files|docs> <id> --remove <path>",summary:"The check spans both item.files and item.docs under one code: restore the missing linked artifact, or unlink it with pm files (linked file) or pm docs (linked doc)."},{code:"validate_files_orphaned_paths",command:"pm <files|docs> <id> --add <path>",summary:"Link the orphaned artifact with pm files (file) or pm docs (doc), or remove it from the workspace."},{code:"validate_files_tracked_all_strict_forces_pm_internals",command:"pm validate --check-files --include-pm-internals",summary:"tracked-all-strict scan flagged pm internals; re-run with --include-pm-internals or a softer --scan-mode."},{code:"validate_history_drift_missing_streams",command:"pm history-repair <id>",summary:"Re-anchor the history chains of the items missing a history stream."},{code:"validate_history_drift_unreadable_streams",command:"pm history-repair <id>",summary:"Re-anchor the history chains of the items with an unreadable history stream."},{code:"validate_history_drift_hash_mismatches",command:"pm history-repair <id>",summary:"Re-anchor the history chains of the items whose content hash drifted."},{code:"validate_history_drift_chain_mismatches",command:"pm history-repair <id>",summary:"Re-anchor the history chains of the items with a broken history chain."},{code:"validate_history_drift_version_skews",command:"npm install -g @unbrained/pm-cli@latest",summary:"One or more history streams declare an item hash version this runtime does not support; upgrade pm to verify the chains instead of re-anchoring them."},{code:"validate_command_references_stale_pm_ids",command:'pm update <id> --replace-tests --test "command=<corrected-command>" [--test ...]',summary:"Correct the stale pm-ID inside the item's linked test command (the check scans tests[].command, not the body). --replace-tests overwrites the entire tests list, so re-include the item's other linked tests in the same call."},{code:"validate_format_version_outdated_items",command:"pm validate --verbose-diagnostics",summary:"One or more items predate the current storage format version; a pm storage migration rewrites them. Use --verbose-diagnostics to list the affected items."},{code:"validate_format_version_ahead_items",command:"npm install -g @unbrained/pm-cli@latest",summary:"One or more items were written by a newer pm format version than this runtime supports; upgrade pm to read and validate them safely."}]);function resolveRemediation(warning){if(typeof warning!=="string"){return void 0}const normalized=warning.trim();for(const entry of REMEDIATION_REGISTRY){if(normalized===entry.code||normalized.startsWith(`${entry.code}:`)){return entry}}return void 0}function buildRemediationMap(warnings){const map={};for(const warning of warnings){const entry=resolveRemediation(warning);if(entry!==void 0&&!Object.prototype.hasOwnProperty.call(map,entry.code)){map[entry.code]=entry.command}}return map}function buildRemediationCommands(warnings){return Object.values(buildRemediationMap(warnings))}export{REMEDIATION_REGISTRY,buildRemediationCommands,buildRemediationMap,resolveRemediation};
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a236314b-1a3b-5499-bed3-364a2cb034a5")}catch(e2){}})();const REMEDIATION_REGISTRY=Object.freeze([{code:"missing_directory",command:"pm init",summary:"Recreate missing tracker directories (pm init is idempotent and restores the scaffold)."},{code:"settings_read_fs_error",command:"pm config list --json",summary:"settings.json could not be read as a regular file and pm fell back to defaults; repair the reported path or permissions, then re-run."},{code:"settings_read_invalid_json",command:"pm config list --json",summary:"settings.json is not valid JSON and pm fell back to defaults; fix the syntax error in the reported path, then re-run."},{code:"settings_read_invalid_schema",command:"pm config list --json",summary:"settings.json failed schema validation and pm fell back to defaults; correct the reported key in the file, then re-run."},{code:"settings_read_merge_failed",command:"pm config list --json",summary:"Global/project settings could not be merged; reconcile the conflicting keys in the reported settings files."},{code:"settings:id_prefix_empty",command:"pm config list --json",summary:'id_prefix is empty; set a non-empty "id_prefix" in settings.json so generated item ids are well-formed.'},{code:"settings:locks_ttl_non_positive",command:"pm config list --json",summary:'locks.ttl_seconds must be positive; set a positive "locks.ttl_seconds" in settings.json.'},{code:"telemetry_state_invalid_json",command:"pm health --check-telemetry",summary:"Local telemetry state file is corrupt; pm recreates it on the next flush. Advisory only."},{code:"telemetry_queue_invalid_rows",command:"pm health --check-telemetry",summary:"The telemetry queue has unparseable rows; they are skipped on the next flush. Advisory only."},{code:"telemetry_queue_pending",command:"pm health --check-telemetry",summary:"Telemetry events are queued; they flush automatically on the next reachable command. Advisory only."},{code:"telemetry_queue_high_retries",command:"pm telemetry flush",summary:"Some queued telemetry events are near retry exhaustion; flush now and verify endpoint reachability before entries are dropped."},{code:"telemetry_endpoint_probe_failed",command:"pm health --check-telemetry",summary:"The telemetry endpoint is unreachable; events stay queued until it recovers. Advisory only."},{code:"telemetry_endpoint_probe_http_status",command:"pm health --check-telemetry",summary:"The telemetry endpoint returned a non-success status; events stay queued until it recovers. Advisory only."},{code:"telemetry_schema_version_behind",command:"pm health --check-telemetry",summary:"Client schema is behind server; upgrade pm-cli to emit the latest event shape."},{code:"telemetry_otel_export_failing",command:"pm health --check-telemetry",summary:"OTLP trace spans are queued but the traces endpoint export is failing; spans retry automatically on the next reachable command, or set PM_TELEMETRY_OTEL_DISABLED=1 to skip OTLP export. Advisory only."},{code:"merge_driver_configuration_missing",command:"pm merge install",summary:"Install the clone-local Git drivers required by the tracker merge fence."},{code:"merge_driver_configuration_drift",command:"pm merge install",summary:"Reinstall clone-local Git drivers after runtime or package paths change."},{code:"validate_merge_driver_configuration",command:"pm merge install",summary:"Restore missing or drifted clone-local Git merge driver commands."},{code:"integrity_item_unreadable",command:"pm validate --check-files --verbose-diagnostics",summary:"An item file could not be read; restore or repair the file at the reported path."},{code:"integrity_item_parse_failed",command:"pm validate --check-files --verbose-diagnostics",summary:"An item file failed to parse; fix the malformed item metadata at the reported path."},{code:"integrity_item_conflict_marker",command:"pm validate --check-files --verbose-diagnostics",summary:"An item file contains Git conflict markers; resolve the <<<<<<< / >>>>>>> markers at the reported line."},{code:"integrity_history_unreadable",command:"pm history-repair <id>",summary:"A history stream could not be read; re-anchor the affected item's history chain."},{code:"integrity_history_invalid_json",command:"pm history-repair <id>",summary:"A history stream contains invalid JSON; re-anchor the affected item's history chain."},{code:"integrity_history_conflict_marker",command:"pm history-repair <id>",summary:"A history stream contains Git conflict markers; resolve the markers, then re-anchor the chain."},{code:"validate_storage_unreadable_items",command:"pm validate --check-storage-integrity --verbose-diagnostics",summary:"An on-disk item file cannot be parsed (for example a botched merge resolution with stale TOON count headers); repair or restore the file at the reported path \u2014 list commands silently skip it while pm get hard-errors."},{code:"validate_storage_duplicate_item_ids",command:"pm validate --check-storage-integrity --verbose-diagnostics",summary:"One item id is claimed by multiple item documents \u2014 usually two branches minting the same id for different items before merging (GH-600). Keep one document, recreate the other item under a fresh id (pm copy, then delete the colliding file), and consider raising ids.token_length for concurrent multi-agent work."},{code:"validate_storage_history_conflict_markers",command:"pm merge driver history <base> <ours> <theirs>",summary:"A history stream contains unresolved Git conflict markers; re-merge it with the pm history merge driver (or resolve the markers by hand), then run pm history-repair for the item."},{code:"validate_storage_unparseable_history",command:"pm history-repair <id>",summary:"A history stream's newest line is not valid JSONL; repair or restore the stream before further mutations."},{code:"validate_storage_resurrected_items",command:"pm delete <id>",summary:"A live item's newest history operation is a delete: a delete/modify merge silently resurrected it. Decide the winner \u2014 re-delete the item, or keep it and append a mutation documenting the revival."},{code:"validate_storage_unparseable_config",command:"pm merge driver json <base> <ours> <theirs>",summary:"settings.json or a schema file cannot be parsed, so pm silently falls back to defaults; re-merge it with the pm JSON merge driver or fix the file by hand, then rerun pm validate."},{code:"validate_merge_fence_drift",command:"pm merge install",summary:"The committed .gitattributes merge fence no longer matches the active schema's type folders or tracker JSONL stores; rerun pm merge install (and commit .gitattributes) so every tracker artifact keeps its field-aware merge driver."},{code:"validate_storage_tracked_runtime_cache_files",command:"git rm --cached -r -- <tracked-runtime-directories>",summary:"Clone-local tracker runtime artifacts are committed. Run the exact tracked_runtime_cache.remediation_command, commit the index-only removals and managed .gitignore fence, then rerun validation."},{code:"integrity_item_outdated_format_version",command:"pm validate --verbose-diagnostics",summary:"An item predates the current storage format version; a pm storage migration rewrites it. Use --verbose-diagnostics to list the affected items."},{code:"integrity_item_ahead_format_version",command:"npm install -g @unbrained/pm-cli@latest",summary:"An item was written by a newer pm format version than this runtime supports; upgrade pm to read and validate it safely."},{code:"tracked_runtime_cache_files",command:"git rm --cached -r -- <tracked-runtime-directories>",summary:"Clone-local tracker runtime artifacts are committed. Run the exact tracked_runtime_cache.remediation_command from the integrity check, commit the index-only removals, and keep the managed .gitignore fence."},{code:"merge_decisions_unreviewed",command:"pm merge reconcile --dry-run",summary:"Review the pending merge receipts, re-apply any intended discarded values, then run pm merge reconcile; lossy receipts require explicit --force acceptance."},{code:"merge_receipts_pending",command:"pm merge reconcile",summary:"A lossless merge receipt is still pending; run pm merge reconcile to settle it (optionally preview first with --dry-run) so a green health gate certifies receipt settlement, not only intact data."},{code:"merge_receipt_evidence_invalid",command:"pm merge report --include-reconciled --json",summary:"One or more receipt candidates failed bounded-file, schema, identity, or copy-consistency validation; inspect the report's privacy-safe source, receipt id, and reason before repairing only the named evidence."},{code:"merge_receipt_history_reference_missing",command:"pm merge reconcile --dry-run",summary:"Review the bounded coordinates and recover available evidence first; for exact pre-durable clone-local-only references, rerun with --force so pm appends an audited disposition and proves the health finding is cleared without rewriting history."},{code:"validate_merge_decisions_unreviewed",command:"pm merge reconcile --dry-run",summary:"Review the pending merge receipts before reconciliation; history-repair alone does not settle them, and lossy receipts require explicit --force acceptance."},{code:"history_drift_missing_stream",command:"pm history-repair <id>",summary:"The item has no history stream; re-anchor the chain to rebuild it (pm history-repair --all repairs every drifted stream in one pass)."},{code:"history_drift_unreadable_stream",command:"pm history-repair <id>",summary:"The item's history stream is unreadable; re-anchor the chain (pm history-repair --all repairs every drifted stream in one pass)."},{code:"history_drift_hash_mismatch",command:"pm history-repair <id>",summary:"The item's content hash no longer matches its history; re-anchor the chain (pm history-repair --all repairs every drifted stream in one pass)."},{code:"history_drift_chain_mismatch",command:"pm history-repair <id>",summary:"The item's history chain is broken; re-anchor the chain (pm history-repair --all repairs every drifted stream in one pass)."},{code:"history_drift_version_skew",command:"npm install -g @unbrained/pm-cli@latest",summary:"A history stream declares an item hash version this runtime does not support; upgrade pm to verify the chain instead of re-anchoring it."},{code:"history_drift_merge_receipt",command:"pm merge reconcile",summary:"Canonical path, changed-field, and merged-value hash evidence attributes this drift to a pending receipt; run reconciliation (optionally preview first with --dry-run) instead of repairing history directly."},{code:"history_stream_over_compact_threshold",command:"pm history-compact <id>",summary:"The history stream exceeds the configured compaction threshold; compact it (pm history-compact --all-streams sweeps every over-threshold stream in one pass)."},{code:"history_unknown_author_events",command:'pm history-author-acknowledge --all-actionable --attributed-author "<principal>" --reviewer "<reviewer>" --reason "<evidence>"',summary:"Review the actionable coordinates, then record an append-only attribution disposition for the complete current set."},{code:"provenance_value_domain_invalid",command:"pm history-repair --all --normalize-provenance",summary:"Remove invalid bounded provenance observations from affected streams and append privacy-safe aggregate repair receipts."},{code:"validate_history_unknown_author_events",command:'pm history-author-acknowledge --all-actionable --attributed-author "<principal>" --reviewer "<reviewer>" --reason "<evidence>"',summary:"Review the actionable coordinates, then record an append-only attribution disposition for the complete current set."},{code:"locks_stale_count",command:"pm gc --scope locks",summary:"Stale item-claim locks (embedded ttl elapsed) can block mutations; sweep them \u2014 gc retains active and unparseable locks."},{code:"locks_unreadable",command:"pm gc --scope locks --dry-run",summary:"Some lock files could not be read; preview the sweep and inspect the unreadable files manually \u2014 gc never deletes what it cannot read."},{code:"extension_update_health_partial_coverage",command:"pm extension --adopt-all --project",summary:"Update-health coverage is partial because unmanaged extensions were skipped; adopt the existing installs into managed metadata so the update scan covers them (use --global for global-scope extensions, or pm package --adopt-all when working with packages)."},{code:"vectorization_stale_items_remaining",command:"pm health --refresh-vectors",summary:"Some items have stale embeddings; refresh vectors so semantic search results stay current."},{code:"vectorization_embedding_identity_changed",command:"pm reindex --mode semantic",summary:"Embedding provider/model changed since the last index; run a semantic reindex to rebuild vectors."},{code:"validate_metadata_missing_closed_at",command:"pm validate --check-metadata --auto-fix --fix-scope timestamps --dry-run",summary:"Preview closure dates proven by verified lifecycle history; inspect residuals and omit --dry-run to apply only proven dates."},{code:"validate_metadata_missing_acceptance_criteria",command:'pm update <id> --acceptance-criteria "<criteria>"',summary:"Backfill the missing acceptance criteria on the reported item(s)."},{code:"validate_metadata_missing_estimate",command:'pm update <id> --estimate "<estimate>"',summary:"Backfill the missing estimate on the reported item(s)."},{code:"validate_metadata_missing_close_reason",command:'pm update <id> --close-reason "<reason>"',summary:"Backfill the missing close reason on the reported closed item(s)."},{code:"validate_metadata_missing_reviewer",command:'pm update <id> --reviewer "<name>"',summary:"Backfill the missing reviewer on the reported item(s)."},{code:"validate_metadata_missing_risk",command:'pm update <id> --risk "<level>"',summary:"Backfill the missing risk on the reported item(s)."},{code:"validate_metadata_missing_confidence",command:'pm update <id> --confidence "<level>"',summary:"Backfill the missing confidence on the reported item(s)."},{code:"validate_metadata_missing_sprint",command:'pm update <id> --sprint "<sprint>"',summary:"Backfill the missing sprint on the reported item(s)."},{code:"validate_metadata_missing_release",command:'pm update <id> --release "<release>"',summary:"Backfill the missing release on the reported item(s)."},{code:"validate_metadata_custom_profile_missing_required_fields",command:'pm config set metadata-required-fields --criterion "<field>"',summary:"Config-driven finding: the custom metadata profile has no required fields configured and falls back to core, so configure the fields rather than mutating items."},{code:"validate_metadata_duplicate_issue_codes",command:'pm update <id> --title "<distinct title>"',summary:"Two or more items share one logical issue code (GH-235); give each a distinct title so the derived code is unique, or close the redundant item with pm close <id> --duplicate-of <canonical-id> (closed-as-duplicate items are excluded from the check)."},{code:"validate_resolution_missing_fields",command:'pm update <id> --resolution "<how resolved>"',summary:"Backfill resolution / expected_result / actual_result on the reported closed item(s)."},{code:"validate_lifecycle_active_closure_like_metadata",command:"pm update <id> --unset <closure-like-field>",summary:"Clear the closure-like field the validator flags on this active item \u2014 the detail row names it (resolution / actual-result / blocked-reason) \u2014 or close the item if it is actually done."},{code:"validate_lifecycle_active_terminal_parent",command:"pm update <id> --parent <active-parent-id>",summary:"Reopen the terminal parent or move the active child under a non-terminal parent."},{code:"validate_lifecycle_stale_blockers",command:"pm update <id> --unset blocked-by --unset blocked-reason",summary:"Resolve the stale blocker the validator flags: clear blocked-by/blocked-reason when they linger on a non-blocked item or report a resolved blocker; if instead a blocked item is missing blocker context, add the context or move it out of a blocked status."},{code:"validate_lifecycle_dependency_cycles_error",command:"pm update <id> --dep-remove <dep-id>",summary:"Break the dependency cycle by removing one edge from the reported cycle."},{code:"validate_lifecycle_dependency_cycles",command:"pm update <id> --dep-remove <dep-id>",summary:"Break the dependency cycle by removing one edge from the reported cycle."},{code:"validate_hierarchy_parent_cycle_error",command:"pm update <id> --parent <other-id>",summary:"Break the parent-hierarchy cycle by reparenting one item in the reported cycle to a non-cyclic parent (or clear it with pm update <id> --unset parent)."},{code:"validate_hierarchy_parent_cycle",command:"pm update <id> --parent <other-id>",summary:"Break the parent-hierarchy cycle by reparenting one item in the reported cycle to a non-cyclic parent (or clear it with pm update <id> --unset parent)."},{code:"validate_files_missing_linked_paths",command:"pm <files|docs> <id> --remove <path>",summary:"The check spans both item.files and item.docs under one code: restore the missing linked artifact, or unlink it with pm files (linked file) or pm docs (linked doc)."},{code:"validate_files_orphaned_paths",command:"pm <files|docs> <id> --add <path>",summary:"Link the orphaned artifact with pm files (file) or pm docs (doc), or remove it from the workspace."},{code:"validate_files_tracked_all_strict_forces_pm_internals",command:"pm validate --check-files --include-pm-internals",summary:"tracked-all-strict scan flagged pm internals; re-run with --include-pm-internals or a softer --scan-mode."},{code:"validate_history_drift_missing_streams",command:"pm history-repair <id>",summary:"Re-anchor the history chains of the items missing a history stream."},{code:"validate_history_drift_unreadable_streams",command:"pm history-repair <id>",summary:"Re-anchor the history chains of the items with an unreadable history stream."},{code:"validate_history_drift_hash_mismatches",command:"pm history-repair <id>",summary:"Re-anchor the history chains of the items whose content hash drifted."},{code:"validate_history_drift_chain_mismatches",command:"pm history-repair <id>",summary:"Re-anchor the history chains of the items with a broken history chain."},{code:"validate_history_drift_version_skews",command:"npm install -g @unbrained/pm-cli@latest",summary:"One or more history streams declare an item hash version this runtime does not support; upgrade pm to verify the chains instead of re-anchoring them."},{code:"validate_command_references_stale_pm_ids",command:'pm update <id> --replace-tests --test "command=<corrected-command>" [--test ...]',summary:"Correct the stale pm-ID inside the item's linked test command (the check scans tests[].command, not the body). --replace-tests overwrites the entire tests list, so re-include the item's other linked tests in the same call."},{code:"validate_format_version_outdated_items",command:"pm validate --verbose-diagnostics",summary:"One or more items predate the current storage format version; a pm storage migration rewrites them. Use --verbose-diagnostics to list the affected items."},{code:"validate_format_version_ahead_items",command:"npm install -g @unbrained/pm-cli@latest",summary:"One or more items were written by a newer pm format version than this runtime supports; upgrade pm to read and validate them safely."}]);function resolveRemediation(warning){if(typeof warning!=="string"){return void 0}const normalized=warning.trim();for(const entry of REMEDIATION_REGISTRY){if(normalized===entry.code||normalized.startsWith(`${entry.code}:`)){return entry}}return void 0}function buildRemediationMap(warnings){const map={};for(const warning of warnings){const entry=resolveRemediation(warning);if(entry!==void 0&&!Object.prototype.hasOwnProperty.call(map,entry.code)){map[entry.code]=entry.command}}return map}function buildRemediationCommands(warnings){return Object.values(buildRemediationMap(warnings))}export{REMEDIATION_REGISTRY,buildRemediationCommands,buildRemediationMap,resolveRemediation};
|
|
2
2
|
//# sourceMappingURL=remediation.js.map
|
|
@@ -26,9 +26,9 @@ export declare const EXTENSION_CAPABILITY_LEGACY_ALIASES: Readonly<Record<string
|
|
|
26
26
|
/** Public contract for extension capability contract, shared by SDK and presentation-layer consumers. */
|
|
27
27
|
export declare const EXTENSION_CAPABILITY_CONTRACT: Readonly<{
|
|
28
28
|
version: 2;
|
|
29
|
-
capabilities: ("search" | "schema" | "commands" | "importers" | "
|
|
29
|
+
capabilities: ("search" | "schema" | "commands" | "importers" | "hooks" | "renderers" | "parser" | "preflight" | "services")[];
|
|
30
30
|
legacy_aliases: {
|
|
31
|
-
[x: string]: "search" | "schema" | "commands" | "importers" | "
|
|
31
|
+
[x: string]: "search" | "schema" | "commands" | "importers" | "hooks" | "renderers" | "parser" | "preflight" | "services";
|
|
32
32
|
};
|
|
33
33
|
}>;
|
|
34
34
|
/** Public contract for known extension policy modes, shared by SDK and presentation-layer consumers. */
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import { assertOptionalStringField, normalizeOptionalStringArrayField } from "./registration-validation.js";
|
|
2
|
-
import { compareComparableVersions, parseComparableVersion } from "./version-compat.js";
|
|
3
1
|
import { type NormalizedExtensionPolicy } from "./extension-policy.js";
|
|
2
|
+
import { type DiscoverExtensionsOptions, type EffectiveExtension, type ExtensionActivationResult, type ExtensionApi, type ExtensionCommandRegistry, type ExtensionDeactivationOptions, type ExtensionDeactivationResult, type ExtensionDiscoveryResult, type ExtensionHookRegistry, type ExtensionLayer, type ExtensionLoadResult, type ExtensionManifest, type ExtensionParserRegistry, type ExtensionPreflightRegistry, type ExtensionRegistrationCounts, type ExtensionRegistrationRegistry, type ExtensionRendererRegistry, type ExtensionServiceRegistry, type FailedExtensionActivation, type LoadedExtension, type PmMaxVersionExceededMode } from "./extension-types.js";
|
|
3
|
+
import { parseExtensionManifestDocument } from "./manifest-parser.js";
|
|
4
|
+
import { assertFlagValueTypeAndDefault, normalizeCommandDefinitionArguments, resolveCommandDefinitionAction, validateItemFieldDefinitions } from "./registration-contracts.js";
|
|
5
|
+
import { assertOptionalStringField, normalizeOptionalStringArrayField } from "./registration-validation.js";
|
|
4
6
|
import { createRegistrationValidationError, extractRegistrationValidationTrace, normalizeRegistrationRecord, normalizeRegistrationRecordList, normalizeRuntimeRegistrationRecord, sanitizeRegistrationValue } from "./registration-values.js";
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
|
|
7
|
+
import { compareComparableVersions, parseComparableVersion } from "./version-compat.js";
|
|
8
|
+
export { parseLegacyExtensionCapabilityAliasWarning, parseUnknownExtensionCapabilityWarning } from "./extension-capability-aliases.js";
|
|
9
|
+
export { createEmptyExtensionCommandRegistry, createEmptyExtensionHookRegistry, createEmptyExtensionParserRegistry, createEmptyExtensionPreflightRegistry, createEmptyExtensionRegistrationRegistry, createEmptyExtensionRendererRegistry, createEmptyExtensionServiceRegistry } from "./extension-registries.js";
|
|
10
|
+
export { runAfterCommandHooks, runBeforeCommandHooks, runBeforeMutationHooks, runCommandHandler, runCommandOverride, runOnIndexHooks, runOnReadHooks, runOnWriteHooks, runParserOverride, runPreflightOverride, runRendererOverride, runServiceOverride, runServiceOverrideSync } from "./extension-hook-runtime.js";
|
|
9
11
|
export * from "./extension-types.js";
|
|
10
|
-
|
|
11
|
-
export declare const DEFAULT_EXTENSION_PRIORITY = 100;
|
|
12
|
+
export { DEFAULT_EXTENSION_PRIORITY, parseExtensionManifestDocument } from "./manifest-parser.js";
|
|
12
13
|
/** Implements next extension reload token for the public runtime surface of this module. */
|
|
13
14
|
export declare function nextExtensionReloadToken(seed?: number): string;
|
|
14
|
-
/** Parse and normalize one complete on-disk extension manifest contract. */
|
|
15
|
-
export declare function parseExtensionManifestDocument(raw: unknown): ExtensionManifest | null;
|
|
16
15
|
/** Resolve symlinks on both paths before the containment check so a link inside the directory cannot escape it. */
|
|
17
16
|
export declare function isCanonicalPathWithinDirectory(directory: string, targetPath: string): Promise<boolean>;
|
|
18
17
|
/** Implements resolve extension roots for the public runtime surface of this module. */
|
|
@@ -52,11 +51,6 @@ export declare function loadExtensions(options: DiscoverExtensionsOptions): Prom
|
|
|
52
51
|
*/
|
|
53
52
|
export declare function deactivateExtensions(loadResult: ExtensionLoadResult, activationResult?: Pick<ExtensionActivationResult, "failed">, options?: ExtensionDeactivationOptions): Promise<ExtensionDeactivationResult>;
|
|
54
53
|
declare function normalizeExtensionDeactivateTimeout(rawTimeout: unknown): number;
|
|
55
|
-
declare function resolveCommandDefinitionAction(commandPath: string, action: unknown): string;
|
|
56
|
-
declare function normalizeCommandDefinitionArguments(value: unknown): ExtensionCommandArgumentDefinition[];
|
|
57
|
-
/** Reject a declared `value_type`/`type` that is not a known flag value kind, and a `default` whose value(s) would not cleanly coerce under that kind — so the typed-flag contract is enforced at registration instead of silently leaving an untyped value to surface at use time. */
|
|
58
|
-
declare function assertFlagValueTypeAndDefault(label: string, record: Record<string, unknown>): void;
|
|
59
|
-
declare function validateItemFieldDefinitions(fields: unknown): void;
|
|
60
54
|
declare function createExtensionApi(extension: LoadedExtension, hooks: ExtensionHookRegistry, commands: ExtensionCommandRegistry, parsers: ExtensionParserRegistry, preflight: ExtensionPreflightRegistry, services: ExtensionServiceRegistry, renderers: ExtensionRendererRegistry, registrations: ExtensionRegistrationRegistry, activationWarnings: string[], activationFailures: FailedExtensionActivation[], policy: NormalizedExtensionPolicy): ExtensionApi;
|
|
61
55
|
declare function getRegistrationCounts(registrations: ExtensionRegistrationRegistry): ExtensionRegistrationCounts;
|
|
62
56
|
declare function collectCommandCollisionWarnings(commands: ExtensionCommandRegistry): string[];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="2f54ac29-9bf8-51f4-9352-8f57d1b5a798")}catch(e2){}})();import fs from"node:fs/promises";import path from"node:path";import{pathToFileURL}from"node:url";import{pathExists}from"../fs/fs-utils.js";import{isPathWithinDirectory}from"../fs/path-utils.js";import{isHostOutputSuppressed,suppressHostOutput}from"../output/output-control.js";import{resolvePmPackageRootFromModule}from"../packages/root.js";import{resolveGlobalPmRoot}from"../store/paths.js";import{asRecordLoose,resolveActivatablePropertyRecord}from"../shared/primitives.js";import{flattenFlagListValue,isFlagDefaultValueCoercible,resolveFlagValueKind}from"./flag-value-types.js";import{KNOWN_ITEM_FIELD_TYPES,normalizeItemFieldType,suggestKnownItemFieldType}from"./item-field-types.js";import{snapshotExtensionModuleGraph}from"./module-graph-snapshot.js";import{captureExtensionActivationRollback}from"./activation-transaction.js";import{collectPreflightCollisionWarnings,normalizePreflightOverride}from"./preflight-ownership.js";import{normalizeServiceOverrideOwnership}from"./service-ownership.js";import{assertCommandDefinitionMetadataStrings}from"./command-visibility-tier.js";import{buildImportExportContext,resolveImportExportArtifactOutput}from"./exporter-output-contract.js";import{asRegistrationRecord,assertOptionalBooleanField,assertOptionalFlagDefaultField,assertOptionalStringArrayField,assertOptionalStringField,normalizeOptionalStringArrayField}from"./registration-validation.js";import{describeExtensionLongFlagFailure,findExtensionFlagTokenFailure}from"./flag-definition-validation.js";import{compareComparableVersions,evaluatePmMaxVersionBound,evaluatePmMinVersionBound,parseComparableVersion}from"./version-compat.js";import{createRelationshipKindRegistry}from"../../sdk/relationships.js";import{normalizeNames,isKnownExtensionCapability,collectUnknownExtensionCapabilities,normalizeManifestCapabilities,formatUnknownExtensionCapabilityWarning,formatLegacyExtensionCapabilityAliasWarning}from"./extension-capability-aliases.js";import{normalizeExtensionPolicy,serializeExtensionPolicy,hydrateExtensionPolicy,normalizePolicySandboxProfile,evaluateExtensionPolicyForExtension,evaluateExtensionPolicyForCapability,evaluateExtensionPolicyForRegistration}from"./extension-policy.js";import{createEmptyExtensionHookRegistry,createEmptyExtensionCommandRegistry,createEmptyExtensionParserRegistry,createEmptyExtensionPreflightRegistry,createEmptyExtensionServiceRegistry,createEmptyExtensionRendererRegistry,createEmptyExtensionRegistrationRegistry}from"./extension-registries.js";import{normalizeCommandName}from"./extension-runtime-helpers.js";import{normalizeExtensionContributionInventory}from"./contribution-inventory.js";import{formatExtensionManifestSchemaWarnings}from"./manifest-schema.js";import{attachRuntimeDefinition,assertHookHandler,assertNonEmptyRegistrationString,assertRegistrationFunction,cloneRuntimeRegistrationValue,createRegistrationValidationError,extractRegistrationValidationTrace,isExtensionServiceName,isOutputRendererFormat,normalizeRegistrationRecord,normalizeRegistrationRecordList,normalizeRuntimeRegistrationRecord,normalizeRegistrationName,sanitizeRegistrationValue,toRegistrationCommandPath,validateAssuranceMeasurementProviderDefinition}from"./registration-values.js";import{buildReadyExtensionCandidate}from"./extension-candidate.js";import{parseUnknownExtensionCapabilityWarning,parseLegacyExtensionCapabilityAliasWarning}from"./extension-capability-aliases.js";import{createEmptyExtensionHookRegistry as createEmptyExtensionHookRegistry2,createEmptyExtensionCommandRegistry as createEmptyExtensionCommandRegistry2,createEmptyExtensionParserRegistry as createEmptyExtensionParserRegistry2,createEmptyExtensionPreflightRegistry as createEmptyExtensionPreflightRegistry2,createEmptyExtensionServiceRegistry as createEmptyExtensionServiceRegistry2,createEmptyExtensionRendererRegistry as createEmptyExtensionRendererRegistry2,createEmptyExtensionRegistrationRegistry as createEmptyExtensionRegistrationRegistry2}from"./extension-registries.js";import{runBeforeCommandHooks,runBeforeMutationHooks,runAfterCommandHooks,runOnWriteHooks,runOnReadHooks,runOnIndexHooks,runCommandHandler,runParserOverride,runPreflightOverride,runServiceOverrideSync,runServiceOverride,runCommandOverride,runRendererOverride}from"./extension-hook-runtime.js";import{KNOWN_EXTENSION_CAPABILITIES,KNOWN_EXTENSION_SERVICE_NAMES,createDefaultExtensionGovernancePolicy}from"./extension-types.js";export*from"./extension-types.js";const DEFAULT_EXTENSION_PRIORITY=100;let currentPmCliVersionPromise=null;const DEFAULT_EXTENSION_POLICY=Object.freeze(createDefaultExtensionGovernancePolicy());let extensionReloadEpoch=0;function nextExtensionReloadToken(seed=Date.now()){extensionReloadEpoch+=1;return`${extensionReloadEpoch}-${seed}`}function parseOptionalManifestString(candidate,field){const value=candidate[field];if(value===void 0||value===null){return void 0}if(typeof value!=="string"||value.trim().length===0){return null}return value.trim()}function parseManifestEngines(value){if(value===void 0||value===null){return void 0}const enginesRecord=asRecordLoose(value);if(!enginesRecord){return null}const engines={};for(const key of Object.keys(enginesRecord).sort((left,right)=>left.localeCompare(right))){if(key.trim().length===0){return null}const engineValue=enginesRecord[key];if(typeof engineValue!=="string"||engineValue.trim().length===0){return null}engines[key.trim()]=engineValue.trim()}return Object.keys(engines).length>0?engines:void 0}function parseRequiredManifestString(candidate,field){const value=candidate[field];if(typeof value!=="string"||value.trim().length===0){return null}return value.trim()}function parseOptionalIntegerValue(value){if(value===void 0||value===null){return void 0}if(typeof value!=="number"||!Number.isInteger(value)){return null}return value}function parseOptionalBooleanValue(value){if(value===void 0||value===null){return void 0}if(typeof value!=="boolean"){return null}return value}function parseManifestPriority(candidate){const value=parseOptionalIntegerValue(candidate.priority);return value===void 0?DEFAULT_EXTENSION_PRIORITY:value}function parseManifestSandboxProfile(candidate){const value=candidate.sandbox_profile;if(value===void 0||value===null){return void 0}if(typeof value!=="string"){return null}const normalizedProfile=normalizePolicySandboxProfile(value);if(normalizedProfile!==value.trim().toLowerCase()){return null}return normalizedProfile}function optionalTrimmedString(value){return typeof value==="string"&&value.trim().length>0?value.trim():void 0}function parseManifestProvenance(value){if(value===void 0||value===null){return void 0}const provenanceRecord=asRecordLoose(value);if(!provenanceRecord){return null}const source=optionalTrimmedString(provenanceRecord.source);const signature=optionalTrimmedString(provenanceRecord.signature);const attestation=optionalTrimmedString(provenanceRecord.attestation);const verified=provenanceRecord.verified===void 0||provenanceRecord.verified===null?void 0:typeof provenanceRecord.verified==="boolean"?provenanceRecord.verified:null;if(verified===null){return null}return{...source?{source}:{},...signature?{signature}:{},...attestation?{attestation}:{},...typeof verified==="boolean"?{verified}:{}}}function parseManifestPermissions(value){if(value===void 0||value===null){return void 0}const permissionsRecord=asRecordLoose(value);if(!permissionsRecord){return null}const fsRead=parseOptionalBooleanValue(permissionsRecord.fs_read);const fsWrite=parseOptionalBooleanValue(permissionsRecord.fs_write);const network=parseOptionalBooleanValue(permissionsRecord.network);const envRead=parseOptionalBooleanValue(permissionsRecord.env_read);const envWrite=parseOptionalBooleanValue(permissionsRecord.env_write);const processSpawn=parseOptionalBooleanValue(permissionsRecord.process_spawn);if([fsRead,fsWrite,network,envRead,envWrite,processSpawn].includes(null)){return null}return{...typeof fsRead==="boolean"?{fs_read:fsRead}:{},...typeof fsWrite==="boolean"?{fs_write:fsWrite}:{},...typeof network==="boolean"?{network}:{},...typeof envRead==="boolean"?{env_read:envRead}:{},...typeof envWrite==="boolean"?{env_write:envWrite}:{},...typeof processSpawn==="boolean"?{process_spawn:processSpawn}:{}}}function parseManifestCapabilities(value){if(value===void 0||value===null){return{capabilities:[],legacy_aliases:[]}}if(!Array.isArray(value)||value.some(entry=>typeof entry!=="string")){return null}const normalizedCapabilities=normalizeManifestCapabilities(value);return{capabilities:normalizedCapabilities.capabilities,legacy_aliases:normalizedCapabilities.legacy_aliases}}function parseManifestActivation(value){if(value===void 0||value===null){return void 0}const activationRecord=asRecordLoose(value);if(!activationRecord){return null}const rawCommands=activationRecord.commands;if(rawCommands===void 0||rawCommands===null){return void 0}if(!Array.isArray(rawCommands)||rawCommands.some(entry=>typeof entry!=="string")){return null}const commands=[...new Set(rawCommands.map(entry=>normalizeCommandName(entry)).filter(entry=>entry.length>0))].sort((left,right)=>left.localeCompare(right));return commands.length>0?{commands}:void 0}function parseManifestMetadata(candidate){const manifestVersion=parseOptionalIntegerValue(candidate.manifest_version);if(manifestVersion===null){return null}const pmMinVersion=parseOptionalManifestString(candidate,"pm_min_version");if(pmMinVersion===null){return null}const pmMaxVersion=parseOptionalManifestString(candidate,"pm_max_version");if(pmMaxVersion===null){return null}const engines=parseManifestEngines(candidate.engines);if(engines===null){return null}const trusted=parseOptionalBooleanValue(candidate.trusted);if(trusted===null){return null}const sandboxProfile=parseManifestSandboxProfile(candidate);if(sandboxProfile===null){return null}const provenance=parseManifestProvenance(candidate.provenance);if(provenance===null){return null}const permissions=parseManifestPermissions(candidate.permissions);if(permissions===null){return null}const capabilities=parseManifestCapabilities(candidate.capabilities);if(capabilities===null){return null}const activation=parseManifestActivation(candidate.activation);if(activation===null){return null}const contributions=normalizeExtensionContributionInventory(candidate.contributions);if(contributions===null){return null}return{manifest_version:manifestVersion,pm_min_version:pmMinVersion,pm_max_version:pmMaxVersion,engines,trusted,sandbox_profile:sandboxProfile,provenance,permissions,capabilities:capabilities.capabilities,legacy_capability_aliases:capabilities.legacy_aliases,activation,contributions}}function parseExtensionManifestDocument(raw){if(typeof raw!=="object"||raw===null){return null}const candidate=raw;const name=parseRequiredManifestString(candidate,"name");if(name===null){return null}const version=parseRequiredManifestString(candidate,"version");if(version===null){return null}const entry=parseRequiredManifestString(candidate,"entry");if(entry===null){return null}const priority=parseManifestPriority(candidate);if(priority===null){return null}const metadata=parseManifestMetadata(candidate);if(metadata===null){return null}return{name,version,entry,priority,manifest_version:metadata.manifest_version,pm_min_version:metadata.pm_min_version,pm_max_version:metadata.pm_max_version,engines:metadata.engines,trusted:metadata.trusted,provenance:metadata.provenance,sandbox_profile:metadata.sandbox_profile,permissions:metadata.permissions,activation:metadata.activation,contributions:metadata.contributions,capabilities:metadata.capabilities,legacy_capability_aliases:metadata.legacy_capability_aliases.length>0?metadata.legacy_capability_aliases:void 0}}function shouldEnable(name,enabled,disabled){if(disabled.has(name)){return false}if(enabled.size===0){return true}return enabled.has(name)}async function isCanonicalPathWithinDirectory(directory,targetPath){const[resolvedDirectory,resolvedTargetPath]=await Promise.all([fs.realpath(directory),fs.realpath(targetPath)]);return isPathWithinDirectory(resolvedDirectory,resolvedTargetPath)}function resolveExtensionRoots(pmRoot,cwd=process.cwd()){return{global:path.join(resolveGlobalPmRoot(cwd),"extensions"),project:path.join(pmRoot,"extensions")}}async function listExtensionDirectories(extensionsRoot){try{const entries=await fs.readdir(extensionsRoot,{withFileTypes:true});return entries.filter(entry=>entry.isDirectory()).map(entry=>entry.name).sort((a,b)=>a.localeCompare(b))}catch{return[]}}function summarizeCandidate(candidate){const summary={layer:candidate.layer,directory:candidate.directory,manifest_path:candidate.manifest_path,name:candidate.manifest.name,version:candidate.manifest.version,entry:candidate.manifest.entry,priority:candidate.manifest.priority,entry_path:candidate.entry_path,manifest_version:candidate.manifest.manifest_version,pm_min_version:candidate.manifest.pm_min_version,pm_max_version:candidate.manifest.pm_max_version,engines:candidate.manifest.engines,trusted:candidate.manifest.trusted,provenance:candidate.manifest.provenance,sandbox_profile:candidate.manifest.sandbox_profile,permissions:candidate.manifest.permissions,capabilities:[...candidate.manifest.capabilities],activation:candidate.manifest.activation?{commands:[...candidate.manifest.activation.commands]}:void 0,contributions:candidate.manifest.contributions??candidate.contributions};if(candidate.source_package){summary.source_package=candidate.source_package}if(candidate.source_aliases){summary.source_aliases=[...candidate.source_aliases]}return summary}function normalizeManagedSourcePackage(value){return typeof value==="string"&&value.trim().length>0?value.trim():void 0}async function readManagedExtensionSourcePackages(extensionsRoot){const packages=new Map;try{const parsed=JSON.parse(await fs.readFile(path.join(extensionsRoot,".managed-extensions.json"),"utf8"));const managedExtensions=asRecordLoose(parsed);const entries=managedExtensions?.entries;if(!Array.isArray(entries)){return packages}for(const entry of entries){if(typeof entry!=="object"||entry===null){continue}const record=entry;const sourcePackage=normalizeManagedSourcePackage(record.source?.package);const aliases=[record.source?.input,record.source?.name,sourcePackage].map(value=>normalizeManagedSourcePackage(value)).filter(value=>value!==void 0);const contributions=normalizeExtensionContributionInventory(record.contributions);const identity={aliases:[...new Set(aliases)],...sourcePackage?{package_name:sourcePackage}:{},...contributions?{contributions}:{}};if(typeof record.directory==="string"&&record.directory.trim().length>0){packages.set(`directory:${record.directory.trim()}`,identity)}if(typeof record.name==="string"&&record.name.trim().length>0){packages.set(`name:${record.name.trim()}`,identity)}}}catch{return packages}return packages}function sortCandidates(candidates){return[...candidates].sort((left,right)=>{if(left.manifest.priority!==right.manifest.priority){return left.manifest.priority-right.manifest.priority}const byName=left.manifest.name.localeCompare(right.manifest.name);if(byName!==0){return byName}return left.directory.localeCompare(right.directory)})}function buildEffectiveExtensions(globalCandidates,projectCandidates){const ordered=[...sortCandidates(globalCandidates),...sortCandidates(projectCandidates)];const effective=[];for(const candidate of ordered){const existingIndex=effective.findIndex(entry=>entry.manifest.name===candidate.manifest.name);if(existingIndex>=0){effective.splice(existingIndex,1)}effective.push(candidate)}return effective}async function scanExtensionLayer(layer,extensionsRoot,enabled,disabled,pmMaxVersionExceededMode){const diagnostics=[];const warnings=[];const candidates=[];const directories=await listExtensionDirectories(extensionsRoot);const managedSourcePackages=await readManagedExtensionSourcePackages(extensionsRoot);for(const directory of directories){const scanned=await scanExtensionDirectory(layer,extensionsRoot,directory,enabled,disabled,managedSourcePackages,pmMaxVersionExceededMode);diagnostics.push(scanned.diagnostic);warnings.push(...scanned.warnings);if(scanned.candidate){candidates.push(scanned.candidate)}}return{diagnostics,warnings,candidates}}function emptyExtensionLayerScan(){return{diagnostics:[],warnings:[],candidates:[]}}function buildUnavailableExtensionScan(layer,directory,manifestPath,warning){return{diagnostic:{layer,directory,manifest_path:manifestPath,name:null,version:null,entry:null,priority:null,entry_path:null,enabled:null,status:"warn"},warnings:[warning],candidate:null}}function collectScannedExtensionWarnings(layer,manifest,rawManifest,entryWithinDirectory,entryExists,pmVersionCompatibility,pmMaxVersionCompatibility){const extensionWarnings=formatExtensionManifestSchemaWarnings(layer,manifest,rawManifest);if(Array.isArray(manifest.legacy_capability_aliases)&&manifest.legacy_capability_aliases.length>0){extensionWarnings.push(formatLegacyExtensionCapabilityAliasWarning(layer,manifest.name,manifest.legacy_capability_aliases))}for(const capability of collectUnknownExtensionCapabilities(manifest.capabilities)){extensionWarnings.push(formatUnknownExtensionCapabilityWarning(layer,manifest.name,capability))}if(!entryWithinDirectory){extensionWarnings.push(`extension_entry_outside_extension:${layer}:${manifest.name}`)}else if(!entryExists){extensionWarnings.push(`extension_entry_missing:${layer}:${manifest.name}`)}if(pmVersionCompatibility.warning){extensionWarnings.push(pmVersionCompatibility.warning)}if(pmMaxVersionCompatibility.warning){extensionWarnings.push(pmMaxVersionCompatibility.warning)}return extensionWarnings}async function scanExtensionDirectory(layer,extensionsRoot,directory,enabled,disabled,managedSourcePackages,pmMaxVersionExceededMode){const extensionDir=path.join(extensionsRoot,directory);const manifestPath=path.join(extensionDir,"manifest.json");if(!await pathExists(manifestPath)){return buildUnavailableExtensionScan(layer,directory,manifestPath,`extension_manifest_missing:${layer}:${directory}`)}let manifest;let rawManifest;try{const parsed=JSON.parse(await fs.readFile(manifestPath,"utf8"));rawManifest=asRecordLoose(parsed);manifest=parseExtensionManifestDocument(parsed)}catch{rawManifest=null;manifest=null}if(!manifest||!rawManifest){return buildUnavailableExtensionScan(layer,directory,manifestPath,`extension_manifest_invalid:${layer}:${directory}`)}const entryPath=path.resolve(extensionDir,manifest.entry);const entryWithinDirectoryByPath=isPathWithinDirectory(extensionDir,entryPath);const entryExists=entryWithinDirectoryByPath?await pathExists(entryPath):false;const entryWithinDirectory=entryWithinDirectoryByPath&&entryExists?await isCanonicalPathWithinDirectory(extensionDir,entryPath):entryWithinDirectoryByPath;const enabledForLoad=shouldEnable(manifest.name,enabled,disabled);const pmVersionCompatibility=await evaluatePmMinVersionCompatibility(layer,manifest);const pmMaxVersionCompatibility=await evaluatePmMaxVersionCompatibility(layer,manifest,pmMaxVersionExceededMode);const extensionWarnings=collectScannedExtensionWarnings(layer,manifest,rawManifest,entryWithinDirectory,entryExists,pmVersionCompatibility,pmMaxVersionCompatibility);const extensionReady=entryWithinDirectory&&entryExists&&pmVersionCompatibility.allowed&&pmMaxVersionCompatibility.allowed;const sourceIdentity=managedSourcePackages.get(`directory:${directory}`)??managedSourcePackages.get(`name:${manifest.name}`);return{diagnostic:{layer,directory,manifest_path:manifestPath,name:manifest.name,version:manifest.version,entry:manifest.entry,priority:manifest.priority,entry_path:entryPath,enabled:enabledForLoad,status:extensionReady?"ok":"warn"},warnings:extensionWarnings,candidate:buildReadyExtensionCandidate({layer,directory,manifestPath,entryPath,manifest,sourceIdentity,extensionReady,enabledForLoad})}}async function discoverExtensions(options){const roots=resolveExtensionRoots(options.pmRoot,options.cwd??process.cwd());const configured_enabled=normalizeNames(options.settings.extensions.enabled);const configured_disabled=normalizeNames(options.settings.extensions.disabled);const policy=normalizeExtensionPolicy(options.settings);const serializedPolicy=serializeExtensionPolicy(policy);if(options.noExtensions){return{disabled_by_flag:true,roots,configured_enabled,configured_disabled,discovered:[],effective:[],warnings:[...policy.warnings],policy:serializedPolicy}}const enabled=new Set(configured_enabled);const disabled=new Set(configured_disabled);const globalScan=options.ignoreGlobalExtensions===true?emptyExtensionLayerScan():await scanExtensionLayer("global",roots.global,enabled,disabled,policy.pmMaxVersionExceededMode.global);const projectScan=await scanExtensionLayer("project",roots.project,enabled,disabled,policy.pmMaxVersionExceededMode.project);const policyWarnings=[...policy.warnings];const effectiveCandidates=buildEffectiveExtensions(globalScan.candidates,projectScan.candidates);const effective=[];for(const candidate of effectiveCandidates){const extensionRef={layer:candidate.layer,name:candidate.manifest.name,trusted:candidate.manifest.trusted===true,provenanceVerified:candidate.manifest.provenance?.verified===true,sandboxProfile:candidate.manifest.sandbox_profile,permissions:candidate.manifest.permissions&&typeof candidate.manifest.permissions==="object"?{fs_read:candidate.manifest.permissions.fs_read,fs_write:candidate.manifest.permissions.fs_write,network:candidate.manifest.permissions.network,env_read:candidate.manifest.permissions.env_read,env_write:candidate.manifest.permissions.env_write,process_spawn:candidate.manifest.permissions.process_spawn}:void 0};const extensionDecision=evaluateExtensionPolicyForExtension(policy,extensionRef);if(extensionDecision.warning){policyWarnings.push(extensionDecision.warning)}if(!extensionDecision.allowed){continue}for(const capability of candidate.manifest.capabilities){const capabilityDecision=evaluateExtensionPolicyForCapability(policy,extensionRef,capability);if(capabilityDecision.warning){policyWarnings.push(capabilityDecision.warning)}}effective.push(summarizeCandidate(candidate))}return{disabled_by_flag:false,roots,configured_enabled,configured_disabled,discovered:[...globalScan.diagnostics,...projectScan.diagnostics],effective,warnings:[...new Set([...globalScan.warnings,...projectScan.warnings,...policyWarnings])],policy:serializedPolicy}}function formatUnknownError(error){if(error instanceof Error&&error.message.trim().length>0){return error.message}return String(error)}async function readCurrentPmCliVersion(){try{const packageRoot=resolvePmPackageRootFromModule(import.meta.url,["../../.."]);const raw=await fs.readFile(path.join(packageRoot,"package.json"),"utf8");const parsed=JSON.parse(raw);return typeof parsed.version==="string"&&parsed.version.trim().length>0?parsed.version.trim():null}catch{return null}}function resolveCurrentPmCliVersion(){currentPmCliVersionPromise??=readCurrentPmCliVersion();return currentPmCliVersionPromise}function formatPmVersionCompatibilityWarning(layer,manifest,evaluation){const current=evaluation.current??"unknown";if(evaluation.kind==="pm_min_version"){switch(evaluation.status){case"invalid":return`extension_pm_min_version_invalid:${layer}:${manifest.name}:required=${evaluation.required}`;case"unchecked":return`extension_pm_min_version_unchecked:${layer}:${manifest.name}:required=${evaluation.required}:current=${current}`;case"unmet":return`extension_pm_min_version_unmet:${layer}:${manifest.name}:required=${evaluation.required}:current=${current}`;default:return void 0}}switch(evaluation.status){case"invalid":return`extension_pm_max_version_invalid:${layer}:${manifest.name}:allowed=${evaluation.required}`;case"unchecked":return`extension_pm_max_version_unchecked:${layer}:${manifest.name}:allowed=${evaluation.required}:current=${current}`;case"exceeded_warn":return`extension_pm_max_version_exceeded_warn:${layer}:${manifest.name}:allowed=${evaluation.required}:current=${current}`;case"exceeded":return`extension_pm_max_version_exceeded:${layer}:${manifest.name}:allowed=${evaluation.required}:current=${current}`;default:return void 0}}async function evaluatePmMinVersionCompatibility(layer,manifest){if(manifest.pm_min_version===void 0){return{allowed:true}}const evaluation=evaluatePmMinVersionBound(manifest.pm_min_version,await resolveCurrentPmCliVersion());const warning=formatPmVersionCompatibilityWarning(layer,manifest,evaluation);return warning?{allowed:evaluation.allowed,warning}:{allowed:evaluation.allowed}}async function evaluatePmMaxVersionCompatibility(layer,manifest,exceededMode){if(manifest.pm_max_version===void 0){return{allowed:true}}const evaluation=evaluatePmMaxVersionBound(manifest.pm_max_version,await resolveCurrentPmCliVersion(),exceededMode);const warning=formatPmVersionCompatibilityWarning(layer,manifest,evaluation);return warning?{allowed:evaluation.allowed,warning}:{allowed:evaluation.allowed}}async function fingerprintPath(pathToInspect){try{const stats=await fs.stat(pathToInspect);return`${Math.trunc(stats.mtimeMs)}-${stats.size}`}catch{return"missing"}}async function resolveExtensionImportHref(extension,options){let importEntryPath=extension.entry_path;if(options.module_graph_snapshot_root){importEntryPath=await snapshotExtensionModuleGraph(options.module_graph_snapshot_root,extension)}const baseUrl=new URL(pathToFileURL(importEntryPath).href);const shouldCacheBust=options.cache_bust===true||typeof options.reload_token==="string";if(!shouldCacheBust){return baseUrl.href}const[entryFingerprint,manifestFingerprint]=await Promise.all([fingerprintPath(extension.entry_path),fingerprintPath(extension.manifest_path)]);const reloadToken=options.reload_token??nextExtensionReloadToken();baseUrl.searchParams.set("pm_ext_reload",reloadToken);baseUrl.searchParams.set("pm_ext_entry",entryFingerprint);baseUrl.searchParams.set("pm_ext_manifest",manifestFingerprint);return baseUrl.href}async function loadExtensions(options){const discovery=await discoverExtensions(options);const loaded=[];const failed=[];const warnings=[...discovery.warnings];if(discovery.disabled_by_flag){return{...discovery,warnings,loaded,failed}}const extensionsToLoad=typeof options.extensionFilter==="function"?discovery.effective.filter(options.extensionFilter):discovery.effective;for(const extension of extensionsToLoad){try{const importHref=await resolveExtensionImportHref(extension,options);const module=await import(importHref);loaded.push({...extension,module})}catch(error){warnings.push(`extension_load_failed:${extension.layer}:${extension.name}`);failed.push({layer:extension.layer,name:extension.name,entry_path:extension.entry_path,error:formatUnknownError(error)})}}return{...discovery,warnings,loaded,failed}}const DEFAULT_EXTENSION_DEACTIVATE_TIMEOUT_MS=5e3;const MAX_EXTENSION_DEACTIVATE_TIMEOUT_MS=2147483647;function toActivatableExtension(source){const activate=source.activate;const activatable={activate:activate.bind(source)};if(typeof source.deactivate==="function"){const deactivate=source.deactivate;activatable.deactivate=deactivate.bind(source)}return activatable}function resolveActivatableExtension(module){const activatableRecord=resolveActivatablePropertyRecord(module);return activatableRecord?toActivatableExtension(activatableRecord):null}async function deactivateExtensions(loadResult,activationResult,options={}){const timeoutMs=normalizeExtensionDeactivateTimeout(options?.deactivate_timeout_ms);const failedActivationKeys=new Set((activationResult?.failed??[]).map(entry=>`${entry.layer}:${entry.name}`));const targets=[];for(const extension of loadResult.loaded){if(failedActivationKeys.has(`${extension.layer}:${extension.name}`)){continue}const activatable=resolveActivatableExtension(extension.module);if(!activatable||typeof activatable.deactivate!=="function"){continue}targets.push({extension,deactivate:activatable.deactivate})}const outcomes=await Promise.all(targets.map(async({extension,deactivate})=>{try{await runExtensionDeactivateWithTimeout(deactivate,timeoutMs);return{ok:true}}catch(error){return{ok:false,layer:extension.layer,name:extension.name,error:formatUnknownError(error)}}}));const warnings=[];const failed=[];let deactivated=0;for(const outcome of outcomes){if(outcome.ok){deactivated+=1;continue}warnings.push(`extension_deactivate_failed:${outcome.layer}:${outcome.name}`);failed.push({layer:outcome.layer,name:outcome.name,error:outcome.error})}return{deactivated,warnings,failed}}function normalizeExtensionDeactivateTimeout(rawTimeout){if(typeof rawTimeout!=="number"||rawTimeout<0){return DEFAULT_EXTENSION_DEACTIVATE_TIMEOUT_MS}if(rawTimeout===0||rawTimeout===Infinity){return 0}if(!Number.isFinite(rawTimeout)){return DEFAULT_EXTENSION_DEACTIVATE_TIMEOUT_MS}return Math.min(MAX_EXTENSION_DEACTIVATE_TIMEOUT_MS,Math.max(1,Math.floor(rawTimeout)))}async function runExtensionDeactivateWithTimeout(deactivate,timeoutMs){if(timeoutMs===0){await deactivate();return}let timeoutHandle;try{const deactivatePromise=Promise.resolve().then(()=>deactivate());deactivatePromise.catch(()=>{});await Promise.race([deactivatePromise,new Promise((_,reject)=>{timeoutHandle=setTimeout(()=>{reject(new Error(`extension deactivate timed out after ${timeoutMs}ms`))},timeoutMs);timeoutHandle.unref?.()})])}finally{clearTimeout(timeoutHandle)}}const FLAG_DEFINITION_KEYS=new Set(["default","description","enabled","list","long","repeatable","required","short","type","value_name","value_type","visible"]);function normalizeFlagDefinitions(name,value){return normalizeRegistrationRecordList(name,value).map(record=>{if(record.repeatable===true){record.list=true}return record})}function normalizeCommandActionName(value){return value.trim().toLowerCase().replace(/[\s_]+/g,"-").replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function resolveCommandDefinitionAction(commandPath,action){if(action===void 0){return commandPath.replace(/\s+/g,"-")}if(typeof action!=="string"||action.trim().length===0){throw new TypeError("registerCommand definition.action must be a non-empty string when provided")}const normalized=normalizeCommandActionName(action);if(normalized.length===0){throw new TypeError("registerCommand definition.action must contain alphanumeric characters")}return normalized}function normalizeCommandDefinitionArguments(value){if(value===void 0){return[]}if(!Array.isArray(value)){throw new TypeError("registerCommand definition.arguments must be an array when provided")}const normalized=[];for(const[index,entry]of value.entries()){const record=asRegistrationRecord(`registerCommand definition.arguments[${index}]`,entry);const name=assertNonEmptyRegistrationString(`registerCommand definition.arguments[${index}].name`,record.name);assertOptionalBooleanField(`registerCommand definition.arguments[${index}].required`,record.required);assertOptionalBooleanField(`registerCommand definition.arguments[${index}].variadic`,record.variadic);assertOptionalStringField(`registerCommand definition.arguments[${index}].description`,record.description);if(name.includes(" ")){throw new TypeError(`registerCommand definition.arguments[${index}].name must not contain spaces`)}const definition={name};if(record.required===true){definition.required=true}if(record.variadic===true){definition.variadic=true}if(typeof record.description==="string"){definition.description=record.description.trim()}normalized.push(definition)}const variadicIndexes=normalized.map((argument,index)=>argument.variadic?index:-1).filter(index=>index>=0);if(variadicIndexes.length>1){throw new TypeError("registerCommand definition.arguments supports at most one variadic argument")}if(variadicIndexes.length===1&&variadicIndexes[0]!==normalized.length-1){throw new TypeError("registerCommand definition.arguments variadic argument must be the final argument")}return normalized}function validateFlagDefinitions(flags){if(!Array.isArray(flags)){throw new TypeError("registerFlags flags requires an array of object definitions")}for(const[index,raw]of flags.entries()){const record=asRegistrationRecord(`registerFlags flags[${index}]`,raw);const unknownKeys=Object.keys(record).filter(key=>!FLAG_DEFINITION_KEYS.has(key)).sort((left,right)=>left.localeCompare(right));if(unknownKeys.length>0){throw new TypeError(`registerFlags flags[${index}] contains unknown field(s): ${unknownKeys.join(", ")}`)}const long=record.long;const short=record.short;if(long===void 0&&short===void 0){throw new TypeError(`registerFlags flags[${index}] requires at least one of long or short`)}assertOptionalStringField(`registerFlags flags[${index}].long`,long);assertOptionalStringField(`registerFlags flags[${index}].short`,short);const tokenFinding=findExtensionFlagTokenFailure(long,short);if(tokenFinding!==null){throw new TypeError(`registerFlags flags[${index}] ${describeExtensionLongFlagFailure(tokenFinding.token,tokenFinding.failure)}`)}assertOptionalStringField(`registerFlags flags[${index}].value_name`,record.value_name);assertOptionalStringField(`registerFlags flags[${index}].description`,record.description);assertOptionalBooleanField(`registerFlags flags[${index}].required`,record.required);assertOptionalBooleanField(`registerFlags flags[${index}].enabled`,record.enabled);assertOptionalBooleanField(`registerFlags flags[${index}].visible`,record.visible);assertOptionalBooleanField(`registerFlags flags[${index}].list`,record.list);assertOptionalBooleanField(`registerFlags flags[${index}].repeatable`,record.repeatable);if(record.list!==void 0&&record.repeatable!==void 0&&record.list!==record.repeatable){throw new TypeError(`registerFlags flags[${index}].list and repeatable must match when both are provided`)}assertOptionalFlagDefaultField(`registerFlags flags[${index}].default`,record.default);if(Array.isArray(record.default)&&record.list!==true&&record.repeatable!==true){throw new TypeError(`registerFlags flags[${index}].default cannot be an array unless list is true.`)}assertFlagValueTypeAndDefault(`registerFlags flags[${index}]`,record)}}function assertFlagValueTypeAndDefault(label,record){const declaredType=(typeof record.value_type==="string"?record.value_type:void 0)??(typeof record.type==="string"?record.type:void 0);if(declaredType===void 0){return}const kind=resolveFlagValueKind(declaredType);if(kind===null){throw new TypeError(`${label} value_type "${declaredType}" is not a known flag value type (expected one of: string, number, boolean).`)}if(record.default===void 0){return}const defaults=record.list===true||record.repeatable===true?flattenFlagListValue(record.default):[record.default];for(const[defaultIndex,defaultValue]of defaults.entries()){if(!isFlagDefaultValueCoercible(defaultValue,kind)){const suffix=defaults.length>1?`default[${defaultIndex}]`:"default";throw new TypeError(`${label}.${suffix} (${JSON.stringify(defaultValue)}) is not coercible to ${kind}.`)}}}function validateItemFieldDefinitions(fields){if(!Array.isArray(fields)){throw new TypeError("registerItemFields fields requires an array of object definitions")}for(const[index,raw]of fields.entries()){const record=asRegistrationRecord(`registerItemFields fields[${index}]`,raw);assertNonEmptyRegistrationString(`registerItemFields fields[${index}].name`,record.name);const fieldType=assertNonEmptyRegistrationString(`registerItemFields fields[${index}].type`,record.type);if(normalizeItemFieldType(fieldType)===null){const suggestion=suggestKnownItemFieldType(fieldType);const hint=suggestion?` Did you mean "${suggestion}"?`:"";throw new TypeError(`registerItemFields fields[${index}].type "${fieldType}" is not a known field type (expected one of: ${KNOWN_ITEM_FIELD_TYPES.join(", ")}).${hint}`)}assertOptionalBooleanField(`registerItemFields fields[${index}].optional`,record.optional)}}function validateItemTypeCommandOptionPolicies(typeIndex,value){if(value===void 0){return}const label=`registerItemTypes types[${typeIndex}].command_option_policies`;if(!Array.isArray(value)){throw new TypeError(`${label} must be an array when provided`)}for(const[policyIndex,rawPolicy]of value.entries()){const at=`${label}[${policyIndex}]`;const policy=asRegistrationRecord(at,rawPolicy);assertNonEmptyRegistrationString(`${at}.command`,policy.command);assertNonEmptyRegistrationString(`${at}.option`,policy.option);assertOptionalBooleanField(`${at}.enabled`,policy.enabled);assertOptionalBooleanField(`${at}.required`,policy.required);assertOptionalBooleanField(`${at}.visible`,policy.visible)}}function validateItemTypeOptions(typeIndex,value){if(value===void 0){return}const label=`registerItemTypes types[${typeIndex}].options`;if(!Array.isArray(value)){throw new TypeError(`${label} must be an array when provided`)}for(const[optionIndex,rawOption]of value.entries()){const at=`${label}[${optionIndex}]`;const option=asRegistrationRecord(at,rawOption);assertNonEmptyRegistrationString(`${at}.key`,option.key);assertOptionalStringArrayField(`${at}.values`,option.values);assertOptionalBooleanField(`${at}.required`,option.required);assertOptionalStringArrayField(`${at}.aliases`,option.aliases)}}function validateItemTypeDefinitions(types){if(!Array.isArray(types)){throw new TypeError("registerItemTypes types requires an array of object definitions")}for(const[typeIndex,raw]of types.entries()){const at=`registerItemTypes types[${typeIndex}]`;const record=asRegistrationRecord(at,raw);assertNonEmptyRegistrationString(`${at}.name`,record.name);assertOptionalStringField(`${at}.folder`,record.folder);assertOptionalStringArrayField(`${at}.aliases`,record.aliases);assertOptionalStringArrayField(`${at}.required_create_fields`,record.required_create_fields);assertOptionalStringArrayField(`${at}.required_create_repeatables`,record.required_create_repeatables);validateItemTypeCommandOptionPolicies(typeIndex,record.command_option_policies);validateItemTypeOptions(typeIndex,record.options)}}function validateMigrationDefinition(definition){const record=asRegistrationRecord("registerMigration definition",definition);if(record.id!==void 0&&typeof record.id!=="string"){throw new TypeError("registerMigration definition.id must be a string when provided")}if(record.description!==void 0&&typeof record.description!=="string"){throw new TypeError("registerMigration definition.description must be a string when provided")}if(record.status!==void 0&&typeof record.status!=="string"){throw new TypeError("registerMigration definition.status must be a string when provided")}assertOptionalBooleanField("registerMigration definition.mandatory",record.mandatory);if(record.run!==void 0&&typeof record.run!=="function"){throw new TypeError("registerMigration definition.run must be a function when provided")}}const PROJECT_PROFILE_DIMENSIONS=["types","statuses","fields","workflows","config","templates","packages"];const PROJECT_PROFILE_ENTRY_VALIDATORS={types:(at,entry)=>{if(entry.name!==void 0&&typeof entry.name!=="string"){throw new TypeError(`${at}.name must be a string when provided`)}},workflows:(at,entry)=>{if(typeof entry.type!=="string"){throw new TypeError(`${at}.type must be a string`)}if(!Array.isArray(entry.allowed_transitions)){throw new TypeError(`${at}.allowed_transitions must be an array`)}for(const[pairIndex,pair]of entry.allowed_transitions.entries()){if(!Array.isArray(pair)){throw new TypeError(`${at}.allowed_transitions[${pairIndex}] must be a [from, to] array`)}}},templates:(at,entry)=>{if(typeof entry.name!=="string"){throw new TypeError(`${at}.name must be a string`)}if(typeof entry.options!=="object"||entry.options===null||Array.isArray(entry.options)){throw new TypeError(`${at}.options must be an object`)}},packages:(at,entry)=>{if(typeof entry.spec!=="string"){throw new TypeError(`${at}.spec must be a string`)}}};function validateProjectProfileDefinition(profile){const record=asRegistrationRecord("registerProfile profile",profile);assertNonEmptyRegistrationString("registerProfile profile.name",record.name);assertNonEmptyRegistrationString("registerProfile profile.title",record.title);if(record.summary!==void 0&&typeof record.summary!=="string"){throw new TypeError("registerProfile profile.summary must be a string when provided")}for(const dimension of PROJECT_PROFILE_DIMENSIONS){const value=record[dimension];if(value===void 0){continue}if(!Array.isArray(value)){throw new TypeError(`registerProfile profile.${dimension} must be an array when provided`)}for(const[index,entry]of value.entries()){if(typeof entry!=="object"||entry===null||Array.isArray(entry)){throw new TypeError(`registerProfile profile.${dimension}[${index}] must be an object`)}PROJECT_PROFILE_ENTRY_VALIDATORS[dimension]?.(`registerProfile profile.${dimension}[${index}]`,entry)}}}function applyProjectProfileDefaults(profile){if(profile.summary===void 0){profile.summary=""}for(const dimension of PROJECT_PROFILE_DIMENSIONS){if(profile[dimension]===void 0){profile[dimension]=[]}}return profile}function getDeclaredExtensionCapabilities(extension){if(!Array.isArray(extension.capabilities)){return null}const declared=new Set;for(const capability of extension.capabilities){const normalized=capability.trim().toLowerCase();if(isKnownExtensionCapability(normalized)){declared.add(normalized)}}return declared}function assertExtensionCapability(extension,capability,method){const declared=getDeclaredExtensionCapabilities(extension);if(declared===null){return}if(!declared.has(capability)){throw createRegistrationValidationError(`${method} requires capability '${capability}' in extension manifest capabilities`,{method,registration_index:-1,capability,missing_capability:capability,expected_schema:`"capabilities": [..., "${capability}"]`,received:extension.capabilities,hint:`Add "${capability}" to ${extension.name} manifest capabilities, or remove the ${method} registration call.`})}}function buildExtensionSelfIdentity(extension){return Object.freeze({name:extension.name,layer:extension.layer,version:extension.version,capabilities:Object.freeze((extension.capabilities??[]).filter(capability=>KNOWN_EXTENSION_CAPABILITIES.includes(capability))),pm_min_version:extension.pm_min_version,pm_max_version:extension.pm_max_version,source_package:extension.source_package})}function buildPolicyExtensionRef(extension){return{layer:extension.layer,name:extension.name,trusted:extension.trusted===true,provenanceVerified:extension.provenance?.verified===true,sandboxProfile:extension.sandbox_profile,permissions:extension.permissions&&typeof extension.permissions==="object"?{fs_read:extension.permissions.fs_read,fs_write:extension.permissions.fs_write,network:extension.permissions.network,env_read:extension.permissions.env_read,env_write:extension.permissions.env_write,process_spawn:extension.permissions.process_spawn}:void 0}}class ExtensionApiRegistrar{extension;hooks;#loadedExtension;#extensionRef;#hookRegistry;#commandRegistry;#parserRegistry;#preflightRegistry;#serviceRegistry;#rendererRegistry;#registrationRegistry;#activationWarnings;#activationFailures;#policy;constructor(extension,hooks,commands,parsers,preflight,services,renderers,registrations,activationWarnings,activationFailures,policy){this.#loadedExtension=extension;this.extension=buildExtensionSelfIdentity(extension);this.#extensionRef=buildPolicyExtensionRef(extension);this.#hookRegistry=hooks;this.#commandRegistry=commands;this.#parserRegistry=parsers;this.#preflightRegistry=preflight;this.#serviceRegistry=services;this.#rendererRegistry=renderers;this.#registrationRegistry=registrations;this.#activationWarnings=activationWarnings;this.#activationFailures=activationFailures;this.#policy=policy;this.registerCommand=this.registerCommand.bind(this);this.registerParser=this.registerParser.bind(this);this.registerPreflight=this.registerPreflight.bind(this);this.registerService=this.registerService.bind(this);this.registerFlags=this.registerFlags.bind(this);this.registerItemFields=this.registerItemFields.bind(this);this.registerItemTypes=this.registerItemTypes.bind(this);this.registerRelationshipKinds=this.registerRelationshipKinds.bind(this);this.registerMigration=this.registerMigration.bind(this);this.registerProfile=this.registerProfile.bind(this);this.registerRenderer=this.registerRenderer.bind(this);this.registerImporter=this.registerImporter.bind(this);this.registerExporter=this.registerExporter.bind(this);this.registerSearchProvider=this.registerSearchProvider.bind(this);this.registerVectorStoreAdapter=this.registerVectorStoreAdapter.bind(this);this.registerAssuranceMeasurementProvider=this.registerAssuranceMeasurementProvider.bind(this);this.hooks={beforeCommand:hook=>this.registerBeforeCommand(hook),beforeMutation:hook=>this.registerBeforeMutation(hook),afterCommand:hook=>this.registerAfterCommand(hook),onWrite:hook=>this.registerOnWrite(hook),onRead:hook=>this.registerOnRead(hook),onIndex:hook=>this.registerOnIndex(hook)}}allowRegistration(surface,method,capability,details){const decision=evaluateExtensionPolicyForRegistration(this.#policy,this.#extensionRef,surface,method,capability,details);if(decision.warning){this.#activationWarnings.push(decision.warning)}return decision.allowed}registerCommandTrace(mode,command,expectedSchema,received,hint){return{method:"registerCommand",registration_index:mode==="override"?this.#commandRegistry.overrides.length:this.#commandRegistry.handlers.length,command,expected_schema:expectedSchema,received:sanitizeRegistrationValue(received),hint}}registerCommandOverride(command,override){const normalizedCommand=normalizeCommandName(command);if(normalizedCommand.length===0){throw createRegistrationValidationError("registerCommand requires a non-empty command name",this.registerCommandTrace("override",command,'registerCommand("<command>", (context) => unknown)',command,"Provide a non-empty command path as the first argument."))}if(typeof override!=="function"){const trace=this.registerCommandTrace("override",normalizedCommand,'registerCommand("<command>", (context) => unknown)',override,"Provide a function as the second registerCommand argument.");throw createRegistrationValidationError(`registerCommand requires an override function when command name is provided (command="${normalizedCommand}", registration_index=${trace.registration_index})`,trace)}if(!this.allowRegistration("commands.override","registerCommand","commands",{command:normalizedCommand})){return}this.#commandRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:normalizedCommand,run:override})}resolveCommandDefinitionRunHandler(definition,normalizedCommand){const runHandler=typeof definition.run==="function"?definition.run:void 0;const legacyHandler=typeof definition.handler==="function"?definition.handler:void 0;if(!runHandler&&legacyHandler){this.#activationWarnings.push(`extension_command_definition_legacy_handler_alias:${this.#loadedExtension.layer}:${this.#loadedExtension.name}:${normalizedCommand}`)}return runHandler??legacyHandler}registerCommandDefinition(definition){if(typeof definition!=="object"||definition===null){throw createRegistrationValidationError("registerCommand requires a command definition object",this.registerCommandTrace("definition",void 0,"{ name: string; run: (context) => unknown; }",definition,'Use registerCommand({ name: "command path", run: (context) => ... }).'))}if(typeof definition.name!=="string"){throw createRegistrationValidationError("registerCommand requires a command definition name",this.registerCommandTrace("definition",void 0,"{ name: string; run: (context) => unknown; }",definition,"Set command definition.name to a non-empty string command path."))}const normalizedCommand=normalizeCommandName(definition.name);if(normalizedCommand.length===0){throw createRegistrationValidationError("registerCommand requires a non-empty command definition name",this.registerCommandTrace("definition",definition.name,"{ name: string; run: (context) => unknown; }",definition,"Ensure command definition.name contains a non-empty command path."))}const resolvedHandler=this.resolveCommandDefinitionRunHandler(definition,normalizedCommand);if(typeof resolvedHandler!=="function"){const trace=this.registerCommandTrace("definition",normalizedCommand,"{ name: string; run: (context) => unknown; }",resolvedHandler,"Define command definition.run as a function.");throw createRegistrationValidationError(`registerCommand requires a command definition run handler (command="${normalizedCommand}", registration_index=${trace.registration_index})`,trace)}try{assertCommandDefinitionMetadataStrings(definition);const action=resolveCommandDefinitionAction(normalizedCommand,definition.action);if(!this.allowRegistration("commands.handler","registerCommand","commands",{command:normalizedCommand,action})){return}const description=definition.description?.trim();const intent=definition.intent?.trim();const examples=normalizeOptionalStringArrayField("registerCommand definition.examples",definition.examples);const failureHints=normalizeOptionalStringArrayField("registerCommand definition.failure_hints",definition.failure_hints);const argumentsDefinition=normalizeCommandDefinitionArguments(definition.arguments);if(definition.flags!==void 0){assertExtensionCapability(this.#loadedExtension,"schema","registerCommand flags");if(this.allowRegistration("schema.flags","registerCommand flags","schema")){validateFlagDefinitions(definition.flags);this.#registrationRegistry.flags.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,target_command:normalizedCommand,flags:normalizeFlagDefinitions("registerCommand definition.flags",definition.flags)})}}const registration={layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,source_package:this.#loadedExtension.source_package,command:normalizedCommand,action,examples,failure_hints:failureHints,arguments:argumentsDefinition,tier:definition.tier??"standard",family:definition.family??"extensions"};if(description){registration.description=description}if(intent){registration.intent=intent}this.#registrationRegistry.commands.push(registration)}catch(error){const reason=formatUnknownError(error);const trace=this.registerCommandTrace("definition",normalizedCommand,"{ name: string; run: (context) => unknown; action?: string; arguments?: object[]; flags?: object[]; }",definition,reason);const validationError=createRegistrationValidationError(`registerCommand definition metadata invalid (command="${normalizedCommand}", registration_index=${trace.registration_index}): ${reason}`,trace);this.#activationWarnings.push(`extension_command_quarantined:${this.#loadedExtension.layer}:${this.#loadedExtension.name}:${normalizedCommand}`);this.#activationFailures.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,entry_path:this.#loadedExtension.entry_path,error:validationError.message,trace});return}this.#commandRegistry.handlers.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:normalizedCommand,run:resolvedHandler})}registerCommand(commandOrDefinition,override){assertExtensionCapability(this.#loadedExtension,"commands","registerCommand");if(typeof commandOrDefinition==="string"){this.registerCommandOverride(commandOrDefinition,override);return}this.registerCommandDefinition(commandOrDefinition)}registerParser(command,override){assertExtensionCapability(this.#loadedExtension,"parser","registerParser");if(!this.allowRegistration("parser.override","registerParser","parser")){return}const normalizedCommand=normalizeCommandName(assertNonEmptyRegistrationString("registerParser command",command));assertRegistrationFunction("registerParser override",override);this.#parserRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:normalizedCommand,run:override})}registerPreflight(override){assertExtensionCapability(this.#loadedExtension,"preflight","registerPreflight");if(!this.allowRegistration("preflight.override","registerPreflight","preflight")){return}const normalized=normalizePreflightOverride(override);this.#preflightRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,...normalized})}registerService(service,override,ownership={}){assertExtensionCapability(this.#loadedExtension,"services","registerService");const normalizedService=String(service).trim().toLowerCase();if(!isExtensionServiceName(normalizedService)){throw new TypeError(`registerService service must be one of: ${KNOWN_EXTENSION_SERVICE_NAMES.join(", ")}`)}if(!this.allowRegistration("services.override","registerService","services",{service:normalizedService})){return}assertRegistrationFunction("registerService override",override);this.#serviceRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,service:normalizedService,run:override,...normalizeServiceOverrideOwnership(ownership)?{passThrough:true}:{}})}registerRenderer(format,renderer,ownership={}){assertExtensionCapability(this.#loadedExtension,"renderers","registerRenderer");if(!this.allowRegistration("renderers.override","registerRenderer","renderers")){return}if(typeof renderer!=="function"){throw new TypeError("registerRenderer requires a renderer function")}const normalizedFormat=String(format).trim().toLowerCase();if(!isOutputRendererFormat(normalizedFormat)){throw new Error(`registerRenderer format must be toon|json, received: ${String(format)}`)}if(ownership.resultDiscriminator!==void 0&&typeof ownership.resultDiscriminator!=="function"){throw new TypeError("registerRenderer ownership.resultDiscriminator must be a function when provided")}const commands=[...new Set((ownership.commands??[]).map(command=>{if(typeof command!=="string"||command.trim().length===0){throw new TypeError("registerRenderer ownership.commands must contain non-empty command paths")}return normalizeCommandName(command)}))];this.#rendererRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,format:normalizedFormat,run:renderer,commands,...ownership.resultDiscriminator?{resultDiscriminator:ownership.resultDiscriminator}:{}})}registerFlags(targetCommand,flags){assertExtensionCapability(this.#loadedExtension,"schema","registerFlags");if(!this.allowRegistration("schema.flags","registerFlags","schema")){return}const normalizedTargetCommand=normalizeCommandName(assertNonEmptyRegistrationString("registerFlags targetCommand",targetCommand));validateFlagDefinitions(flags);const normalizedFlags=normalizeFlagDefinitions("registerFlags flags",flags);if(normalizedFlags.length===0){throw new TypeError("registerFlags requires at least one flag definition")}this.#registrationRegistry.flags.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,target_command:normalizedTargetCommand,flags:normalizedFlags})}registerItemFields(fields){assertExtensionCapability(this.#loadedExtension,"schema","registerItemFields");if(!this.allowRegistration("schema.itemfields","registerItemFields","schema")){return}validateItemFieldDefinitions(fields);const normalizedFields=normalizeRegistrationRecordList("registerItemFields fields",fields);if(normalizedFields.length===0){throw new TypeError("registerItemFields requires at least one field definition")}this.#registrationRegistry.item_fields.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,fields:normalizedFields})}registerItemTypes(types){assertExtensionCapability(this.#loadedExtension,"schema","registerItemTypes");if(!this.allowRegistration("schema.itemtypes","registerItemTypes","schema")){return}validateItemTypeDefinitions(types);const normalizedTypes=normalizeRegistrationRecordList("registerItemTypes types",types);if(normalizedTypes.length===0){throw new TypeError("registerItemTypes requires at least one type definition")}this.#registrationRegistry.item_types.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,types:normalizedTypes})}registerRelationshipKinds(definitions){assertExtensionCapability(this.#loadedExtension,"schema","registerRelationshipKinds");if(!this.allowRegistration("schema.relationshipkinds","registerRelationshipKinds","schema")){return}if(!Array.isArray(definitions)){throw new TypeError("registerRelationshipKinds definitions requires an array of object definitions")}if(definitions.length===0){throw new TypeError("registerRelationshipKinds requires at least one definition")}const registry=createRelationshipKindRegistry();for(const registration of this.#registrationRegistry.relationship_kinds){for(const definition of registration.definitions){registry.register(definition)}}const validated=definitions.map(definition=>{registry.register(definition);return registry.require(definition.kind)});this.#registrationRegistry.relationship_kinds.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,definitions:validated})}registerMigration(definition){assertExtensionCapability(this.#loadedExtension,"schema","registerMigration");if(!this.allowRegistration("schema.migrations","registerMigration","schema")){return}validateMigrationDefinition(definition);const runtimeDefinition=normalizeRuntimeRegistrationRecord("registerMigration definition",definition);this.#registrationRegistry.migrations.push(attachRuntimeDefinition({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,definition:normalizeRegistrationRecord("registerMigration definition",definition)},runtimeDefinition))}registerProfile(profile){assertExtensionCapability(this.#loadedExtension,"schema","registerProfile");if(!this.allowRegistration("schema.profiles","registerProfile","schema")){return}const snapshot=cloneRuntimeRegistrationValue(profile);validateProjectProfileDefinition(snapshot);this.#registrationRegistry.profiles.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,profile:applyProjectProfileDefaults(snapshot)})}registerImportExportCommandFlags(method,commandPath,resolvedOptions){if(resolvedOptions.flags===void 0){return}assertExtensionCapability(this.#loadedExtension,"schema",`${method} options.flags`);if(!this.allowRegistration("schema.flags",`${method} options.flags`,"schema")){return}validateFlagDefinitions(resolvedOptions.flags);this.#registrationRegistry.flags.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,target_command:commandPath,flags:normalizeFlagDefinitions(`${method} options.flags`,resolvedOptions.flags)})}applyImportExportCommandMetadata(method,commandPath,options){if(options!==void 0&&(typeof options!=="object"||options===null||Array.isArray(options))){throw new TypeError(`${method} options must be an object when provided`)}const defaultDescription=`${method==="registerImporter"?"Import":"Export"} items with the registered extension adapter.`;const defaultArguments=[{name:"file",required:false,description:"Optional input or output file path."}];const resolvedOptions={...options,description:options?.description??defaultDescription,arguments:options?.arguments??defaultArguments};const output=resolveImportExportArtifactOutput(method,resolvedOptions,options?.description!==void 0);assertOptionalStringField(`${method} options.action`,resolvedOptions.action);assertOptionalStringField(`${method} options.description`,resolvedOptions.description);assertOptionalStringField(`${method} options.intent`,resolvedOptions.intent);const action=resolveCommandDefinitionAction(commandPath,resolvedOptions.action);const examples=normalizeOptionalStringArrayField(`${method} options.examples`,resolvedOptions.examples);const failureHints=normalizeOptionalStringArrayField(`${method} options.failure_hints`,resolvedOptions.failure_hints);const argumentsDefinition=normalizeCommandDefinitionArguments(resolvedOptions.arguments);this.registerImportExportCommandFlags(method,commandPath,resolvedOptions);const registration={layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,source_package:this.#loadedExtension.source_package,command:commandPath,action,examples,failure_hints:failureHints,arguments:argumentsDefinition};const description=resolvedOptions.description?.trim();if(description){registration.description=description}const intent=resolvedOptions.intent?.trim();if(intent){registration.intent=intent}this.#registrationRegistry.commands.push(registration);return output}registerImporter(name,importer,options){assertExtensionCapability(this.#loadedExtension,"importers","registerImporter");if(!this.allowRegistration("importers.importer","registerImporter","importers")){return}const normalizedName=normalizeRegistrationName(assertNonEmptyRegistrationString("registerImporter name",name));assertRegistrationFunction("registerImporter importer",importer);const commandPath=toRegistrationCommandPath(normalizedName,"import");this.applyImportExportCommandMetadata("registerImporter",commandPath,options);this.#registrationRegistry.importers.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,importer:normalizedName});this.#commandRegistry.handlers.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:commandPath,run:async context=>importer(buildImportExportContext(context,normalizedName,"import"))})}registerExporter(name,exporter,options){assertExtensionCapability(this.#loadedExtension,"importers","registerExporter");if(!this.allowRegistration("importers.exporter","registerExporter","importers")){return}const normalizedName=normalizeRegistrationName(assertNonEmptyRegistrationString("registerExporter name",name));assertRegistrationFunction("registerExporter exporter",exporter);const commandPath=toRegistrationCommandPath(normalizedName,"export");const output=this.applyImportExportCommandMetadata("registerExporter",commandPath,options);this.#registrationRegistry.exporters.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,exporter:normalizedName,...output===void 0?{}:{output}});this.#commandRegistry.handlers.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:commandPath,run:async context=>{const result=await exporter(buildImportExportContext(context,normalizedName,"export"));return output?.receipt==="suppress"&&!isHostOutputSuppressed(result)?suppressHostOutput(result):result}})}registerSearchProvider(provider){assertExtensionCapability(this.#loadedExtension,"search","registerSearchProvider");if(!this.allowRegistration("search.provider","registerSearchProvider","search")){return}const runtimeDefinition=normalizeRuntimeRegistrationRecord("registerSearchProvider provider",provider);this.#registrationRegistry.search_providers.push(attachRuntimeDefinition({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,definition:normalizeRegistrationRecord("registerSearchProvider provider",provider)},runtimeDefinition))}registerVectorStoreAdapter(adapter){assertExtensionCapability(this.#loadedExtension,"search","registerVectorStoreAdapter");if(!this.allowRegistration("search.vectorstore","registerVectorStoreAdapter","search")){return}const runtimeDefinition=normalizeRuntimeRegistrationRecord("registerVectorStoreAdapter adapter",adapter);this.#registrationRegistry.vector_store_adapters.push(attachRuntimeDefinition({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,definition:normalizeRegistrationRecord("registerVectorStoreAdapter adapter",adapter)},runtimeDefinition))}registerAssuranceMeasurementProvider(provider){assertExtensionCapability(this.#loadedExtension,"services","registerAssuranceMeasurementProvider");if(!this.allowRegistration("services.assuranceprovider","registerAssuranceMeasurementProvider","services")){return}validateAssuranceMeasurementProviderDefinition(provider);if(provider.network&&this.#loadedExtension.permissions?.network!==true){throw new TypeError("registerAssuranceMeasurementProvider network provider requires permissions.network=true")}const runtimeDefinition=normalizeRuntimeRegistrationRecord("registerAssuranceMeasurementProvider provider",provider);this.#registrationRegistry.assurance_providers.push(attachRuntimeDefinition({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,network_permission:this.#loadedExtension.permissions?.network===true,definition:normalizeRegistrationRecord("registerAssuranceMeasurementProvider provider",provider)},runtimeDefinition))}registerBeforeCommand(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.beforeCommand");if(!this.allowRegistration("hooks.beforecommand","api.hooks.beforeCommand","hooks"))return;assertHookHandler("beforeCommand",hook);this.#hookRegistry.beforeCommand.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerBeforeMutation(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.beforeMutation");if(!this.allowRegistration("hooks.beforemutation","api.hooks.beforeMutation","hooks"))return;assertHookHandler("beforeMutation",hook);this.#hookRegistry.beforeMutation.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerAfterCommand(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.afterCommand");if(!this.allowRegistration("hooks.aftercommand","api.hooks.afterCommand","hooks"))return;assertHookHandler("afterCommand",hook);this.#hookRegistry.afterCommand.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerOnWrite(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.onWrite");if(!this.allowRegistration("hooks.onwrite","api.hooks.onWrite","hooks"))return;assertHookHandler("onWrite",hook);this.#hookRegistry.onWrite.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerOnRead(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.onRead");if(!this.allowRegistration("hooks.onread","api.hooks.onRead","hooks"))return;assertHookHandler("onRead",hook);this.#hookRegistry.onRead.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerOnIndex(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.onIndex");if(!this.allowRegistration("hooks.onindex","api.hooks.onIndex","hooks"))return;assertHookHandler("onIndex",hook);this.#hookRegistry.onIndex.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}}function createExtensionApi(extension,hooks,commands,parsers,preflight,services,renderers,registrations,activationWarnings,activationFailures,policy){return new ExtensionApiRegistrar(extension,hooks,commands,parsers,preflight,services,renderers,registrations,activationWarnings,activationFailures,policy)}function getRegistrationCounts(registrations){const commandCount=registrations.commands.length;const flagCount=registrations.flags.reduce((total,entry)=>total+entry.flags.length,0);const itemFieldCount=registrations.item_fields.reduce((total,entry)=>total+entry.fields.length,0);const itemTypeCount=registrations.item_types.reduce((total,entry)=>total+entry.types.length,0);const relationshipKindCount=(registrations.relationship_kinds??[]).reduce((total,entry)=>total+entry.definitions.length,0);return{commands:commandCount,flags:flagCount,item_fields:itemFieldCount,item_types:itemTypeCount,...relationshipKindCount>0?{relationship_kinds:relationshipKindCount}:{},migrations:registrations.migrations.length,profiles:registrations.profiles.length,importers:registrations.importers.length,exporters:registrations.exporters.length,search_providers:registrations.search_providers.length,vector_store_adapters:registrations.vector_store_adapters.length,...(registrations.assurance_providers?.length??0)>0?{assurance_providers:registrations.assurance_providers.length}:{}}}function collectCommandCollisionWarnings(commands){const warnings=[];const collectByCommand=(entries,codePrefix)=>{const grouped=new Map;for(const entry of entries){const bucket=grouped.get(entry.command)??[];bucket.push(entry);grouped.set(entry.command,bucket)}for(const command of[...grouped.keys()].sort((left,right)=>left.localeCompare(right))){const bucket=grouped.get(command);if(bucket.length<=1){continue}const winner=bucket[bucket.length-1];for(const displaced of bucket.slice(0,-1)){warnings.push(`${codePrefix}:${command}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`)}}};collectByCommand(commands.handlers,"extension_command_handler_collision");collectByCommand(commands.overrides,"extension_command_override_collision");const handlerCommands=new Set(commands.handlers.map(entry=>entry.command));const overlapCommands=[...new Set(commands.overrides.map(entry=>entry.command))].filter(command=>handlerCommands.has(command));overlapCommands.sort((left,right)=>left.localeCompare(right));for(const command of overlapCommands){const handlers=commands.handlers.filter(entry=>entry.command===command);const overrides=commands.overrides.filter(entry=>entry.command===command);for(const override of overrides){for(const handler of handlers){warnings.push(`extension_command_override_handler_overlap:${command}:${override.layer}:${override.name}:${handler.layer}:${handler.name}`)}}}return warnings}function collectRendererCollisionWarnings(renderers){const grouped=new Map;for(const entry of renderers.overrides){const bucket=grouped.get(entry.format)??[];bucket.push(entry);grouped.set(entry.format,bucket)}const warnings=[];for(const format of[...grouped.keys()].sort((left,right)=>left.localeCompare(right))){const bucket=grouped.get(format);if(bucket.length<=1){continue}const winner=bucket[bucket.length-1];for(const displaced of bucket.slice(0,-1)){if(winner.commands?.length&&displaced.commands?.length&&!displaced.commands.some(command=>winner.commands?.includes(command))){continue}warnings.push(`extension_renderer_collision:${format}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`)}}return warnings}function collectParserCollisionWarnings(parsers){const warnings=[];const grouped=new Map;for(const entry of parsers.overrides){const bucket=grouped.get(entry.command)??[];bucket.push(entry);grouped.set(entry.command,bucket)}for(const command of[...grouped.keys()].sort((left,right)=>left.localeCompare(right))){const bucket=grouped.get(command);if(bucket.length<=1){continue}const winner=bucket[bucket.length-1];for(const displaced of bucket.slice(0,-1)){warnings.push(`extension_parser_override_collision:${command}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`)}}return warnings}const CHAINED_SERVICE_NAMES=new Set(["output_format"]);function collectServiceCollisionWarnings(services){const warnings=[];const grouped=new Map;for(const entry of services.overrides){const bucket=grouped.get(entry.service)??[];bucket.push(entry);grouped.set(entry.service,bucket)}for(const service of[...grouped.keys()].sort((left,right)=>left.localeCompare(right))){const bucket=grouped.get(service);if(bucket.length<=1){continue}if(CHAINED_SERVICE_NAMES.has(service)){continue}const winner=bucket[bucket.length-1];for(const displaced of bucket.slice(0,-1)){warnings.push(`extension_service_override_collision:${service}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`)}}return warnings}async function activateExtensions(loadResult){const policy=hydrateExtensionPolicy(loadResult.policy??DEFAULT_EXTENSION_POLICY);const hooks=createEmptyExtensionHookRegistry();const commands=createEmptyExtensionCommandRegistry();const parsers=createEmptyExtensionParserRegistry();const preflight=createEmptyExtensionPreflightRegistry();const services=createEmptyExtensionServiceRegistry();const renderers=createEmptyExtensionRendererRegistry();const registrations=createEmptyExtensionRegistrationRegistry();const failed=[];const warnings=[];for(const extension of loadResult.loaded){const activatable=resolveActivatableExtension(extension.module);if(!activatable){continue}const failedBeforeActivation=failed.length;const rollbackPartialActivation=captureExtensionActivationRollback({hooks,commands,parsers,preflight,services,renderers,registrations});try{await activatable.activate(createExtensionApi(extension,hooks,commands,parsers,preflight,services,renderers,registrations,warnings,failed,policy));if(failed.length>failedBeforeActivation){rollbackPartialActivation();warnings.push(`extension_activation_rolled_back:${extension.layer}:${extension.name}`)}}catch(error){rollbackPartialActivation();warnings.push(`extension_activate_failed:${extension.layer}:${extension.name}`);const trace=extractRegistrationValidationTrace(error);failed.push({layer:extension.layer,name:extension.name,entry_path:extension.entry_path,error:formatUnknownError(error),trace})}}const collisionWarnings=[...collectCommandCollisionWarnings(commands),...collectParserCollisionWarnings(parsers),...collectPreflightCollisionWarnings(preflight),...collectServiceCollisionWarnings(services),...collectRendererCollisionWarnings(renderers)];const mergedWarnings=[...new Set([...warnings,...collisionWarnings])];return{hooks,commands,parsers,preflight,services,renderers,registrations,failed,warnings:mergedWarnings,hook_counts:{before_command:hooks.beforeCommand.length,before_mutation:hooks.beforeMutation.length,after_command:hooks.afterCommand.length,on_write:hooks.onWrite.length,on_read:hooks.onRead.length,on_index:hooks.onIndex.length},command_override_count:commands.overrides.length,command_handler_count:commands.handlers.length,parser_override_count:parsers.overrides.length,preflight_override_count:preflight.overrides.length,service_override_count:services.overrides.length,renderer_override_count:renderers.overrides.length,registration_counts:getRegistrationCounts(registrations)}}const _testOnlyLoader={assertFlagValueTypeAndDefault,assertOptionalStringField,compareComparableVersions,collectCommandCollisionWarnings,collectParserCollisionWarnings,collectRendererCollisionWarnings,collectServiceCollisionWarnings,createExtensionApi,createRegistrationValidationError,evaluatePmMaxVersionCompatibility,evaluatePmMinVersionCompatibility,extractRegistrationValidationTrace,fingerprintPath,getRegistrationCounts,normalizeCommandDefinitionArguments,normalizeExtensionDeactivateTimeout,normalizeOptionalStringArrayField,normalizeRegistrationRecord,normalizeRegistrationRecordList,normalizeRuntimeRegistrationRecord,parseComparableVersion,parseManifest:parseExtensionManifestDocument,readCurrentPmCliVersion,readManagedExtensionSourcePackages:async extensionsRoot=>new Map([...await readManagedExtensionSourcePackages(extensionsRoot)].filter(entry=>typeof entry[1].package_name==="string").map(([key,identity])=>[key,identity.package_name])),resolveExtensionImportHref,resolveCurrentPmCliVersion,resolveCommandDefinitionAction,sanitizeRegistrationValue,validateItemFieldDefinitions,resetCurrentPmCliVersionCacheForTest:()=>{currentPmCliVersionPromise=null}};export{DEFAULT_EXTENSION_PRIORITY,_testOnlyLoader,activateExtensions,createEmptyExtensionCommandRegistry2 as createEmptyExtensionCommandRegistry,createEmptyExtensionHookRegistry2 as createEmptyExtensionHookRegistry,createEmptyExtensionParserRegistry2 as createEmptyExtensionParserRegistry,createEmptyExtensionPreflightRegistry2 as createEmptyExtensionPreflightRegistry,createEmptyExtensionRegistrationRegistry2 as createEmptyExtensionRegistrationRegistry,createEmptyExtensionRendererRegistry2 as createEmptyExtensionRendererRegistry,createEmptyExtensionServiceRegistry2 as createEmptyExtensionServiceRegistry,deactivateExtensions,discoverExtensions,isCanonicalPathWithinDirectory,loadExtensions,nextExtensionReloadToken,parseExtensionManifestDocument,parseLegacyExtensionCapabilityAliasWarning,parseUnknownExtensionCapabilityWarning,resolveExtensionRoots,runAfterCommandHooks,runBeforeCommandHooks,runBeforeMutationHooks,runCommandHandler,runCommandOverride,runOnIndexHooks,runOnReadHooks,runOnWriteHooks,runParserOverride,runPreflightOverride,runRendererOverride,runServiceOverride,runServiceOverrideSync};
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3ee03fc2-5b71-508c-8524-d22104fa2194")}catch(e2){}})();import fs from"node:fs/promises";import path from"node:path";import{pathToFileURL}from"node:url";import{createRelationshipKindRegistry}from"../../sdk/relationships.js";import{pathExists}from"../fs/fs-utils.js";import{isPathWithinDirectory}from"../fs/path-utils.js";import{isHostOutputSuppressed,suppressHostOutput}from"../output/output-control.js";import{resolvePmPackageRootFromModule}from"../packages/root.js";import{asRecordLoose,resolveActivatablePropertyRecord}from"../shared/primitives.js";import{resolveGlobalPmRoot}from"../store/paths.js";import{captureExtensionActivationRollback}from"./activation-transaction.js";import{assertCommandDefinitionMetadataStrings}from"./command-visibility-tier.js";import{normalizeExtensionContributionInventory}from"./contribution-inventory.js";import{buildImportExportContext,resolveImportExportArtifactOutput}from"./exporter-output-contract.js";import{buildReadyExtensionCandidate}from"./extension-candidate.js";import{collectUnknownExtensionCapabilities,formatLegacyExtensionCapabilityAliasWarning,formatUnknownExtensionCapabilityWarning,isKnownExtensionCapability,normalizeNames}from"./extension-capability-aliases.js";import{evaluateExtensionPolicyForCapability,evaluateExtensionPolicyForExtension,evaluateExtensionPolicyForRegistration,hydrateExtensionPolicy,normalizeExtensionPolicy,serializeExtensionPolicy}from"./extension-policy.js";import{createEmptyExtensionCommandRegistry,createEmptyExtensionHookRegistry,createEmptyExtensionParserRegistry,createEmptyExtensionPreflightRegistry,createEmptyExtensionRegistrationRegistry,createEmptyExtensionRendererRegistry,createEmptyExtensionServiceRegistry}from"./extension-registries.js";import{normalizeCommandName}from"./extension-runtime-helpers.js";import{KNOWN_EXTENSION_CAPABILITIES,KNOWN_EXTENSION_SERVICE_NAMES,createDefaultExtensionGovernancePolicy}from"./extension-types.js";import{parseExtensionManifestDocument}from"./manifest-parser.js";import{formatExtensionManifestSchemaWarnings}from"./manifest-schema.js";import{snapshotExtensionModuleGraph}from"./module-graph-snapshot.js";import{collectPreflightCollisionWarnings,normalizePreflightOverride}from"./preflight-ownership.js";import{applyProjectProfileDefaults,assertFlagValueTypeAndDefault,normalizeCommandDefinitionArguments,normalizeFlagDefinitions,resolveCommandDefinitionAction,validateFlagDefinitions,validateItemFieldDefinitions,validateItemTypeDefinitions,validateMigrationDefinition,validateProjectProfileDefinition}from"./registration-contracts.js";import{assertOptionalStringField,normalizeOptionalStringArrayField}from"./registration-validation.js";import{assertHookHandler,assertNonEmptyRegistrationString,assertRegistrationFunction,attachRuntimeDefinition,cloneRuntimeRegistrationValue,createRegistrationValidationError,extractRegistrationValidationTrace,isExtensionServiceName,isOutputRendererFormat,normalizeRegistrationName,normalizeRegistrationRecord,normalizeRegistrationRecordList,normalizeRuntimeRegistrationRecord,sanitizeRegistrationValue,toRegistrationCommandPath,validateAssuranceMeasurementProviderDefinition}from"./registration-values.js";import{normalizeServiceOverrideOwnership}from"./service-ownership.js";import{compareComparableVersions,evaluatePmMaxVersionBound,evaluatePmMinVersionBound,parseComparableVersion}from"./version-compat.js";import{parseLegacyExtensionCapabilityAliasWarning,parseUnknownExtensionCapabilityWarning}from"./extension-capability-aliases.js";import{createEmptyExtensionCommandRegistry as createEmptyExtensionCommandRegistry2,createEmptyExtensionHookRegistry as createEmptyExtensionHookRegistry2,createEmptyExtensionParserRegistry as createEmptyExtensionParserRegistry2,createEmptyExtensionPreflightRegistry as createEmptyExtensionPreflightRegistry2,createEmptyExtensionRegistrationRegistry as createEmptyExtensionRegistrationRegistry2,createEmptyExtensionRendererRegistry as createEmptyExtensionRendererRegistry2,createEmptyExtensionServiceRegistry as createEmptyExtensionServiceRegistry2}from"./extension-registries.js";import{runAfterCommandHooks,runBeforeCommandHooks,runBeforeMutationHooks,runCommandHandler,runCommandOverride,runOnIndexHooks,runOnReadHooks,runOnWriteHooks,runParserOverride,runPreflightOverride,runRendererOverride,runServiceOverride,runServiceOverrideSync}from"./extension-hook-runtime.js";export*from"./extension-types.js";import{DEFAULT_EXTENSION_PRIORITY,parseExtensionManifestDocument as parseExtensionManifestDocument2}from"./manifest-parser.js";let currentPmCliVersionPromise=null;const DEFAULT_EXTENSION_POLICY=Object.freeze(createDefaultExtensionGovernancePolicy());let extensionReloadEpoch=0;function nextExtensionReloadToken(seed=Date.now()){extensionReloadEpoch+=1;return`${extensionReloadEpoch}-${seed}`}function shouldEnable(name,enabled,disabled){if(disabled.has(name)){return false}if(enabled.size===0){return true}return enabled.has(name)}async function isCanonicalPathWithinDirectory(directory,targetPath){const[resolvedDirectory,resolvedTargetPath]=await Promise.all([fs.realpath(directory),fs.realpath(targetPath)]);return isPathWithinDirectory(resolvedDirectory,resolvedTargetPath)}function resolveExtensionRoots(pmRoot,cwd=process.cwd()){return{global:path.join(resolveGlobalPmRoot(cwd),"extensions"),project:path.join(pmRoot,"extensions")}}async function listExtensionDirectories(extensionsRoot){try{const entries=await fs.readdir(extensionsRoot,{withFileTypes:true});return entries.filter(entry=>entry.isDirectory()).map(entry=>entry.name).sort((a,b)=>a.localeCompare(b))}catch{return[]}}function summarizeCandidate(candidate){const summary={layer:candidate.layer,directory:candidate.directory,manifest_path:candidate.manifest_path,name:candidate.manifest.name,version:candidate.manifest.version,entry:candidate.manifest.entry,priority:candidate.manifest.priority,entry_path:candidate.entry_path,manifest_version:candidate.manifest.manifest_version,pm_min_version:candidate.manifest.pm_min_version,pm_max_version:candidate.manifest.pm_max_version,engines:candidate.manifest.engines,trusted:candidate.manifest.trusted,provenance:candidate.manifest.provenance,sandbox_profile:candidate.manifest.sandbox_profile,permissions:candidate.manifest.permissions,capabilities:[...candidate.manifest.capabilities],activation:candidate.manifest.activation?{commands:[...candidate.manifest.activation.commands]}:void 0,contributions:candidate.manifest.contributions??candidate.contributions};if(candidate.source_package){summary.source_package=candidate.source_package}if(candidate.source_aliases){summary.source_aliases=[...candidate.source_aliases]}return summary}function normalizeManagedSourcePackage(value){return typeof value==="string"&&value.trim().length>0?value.trim():void 0}async function readManagedExtensionSourcePackages(extensionsRoot){const packages=new Map;try{const parsed=JSON.parse(await fs.readFile(path.join(extensionsRoot,".managed-extensions.json"),"utf8"));const managedExtensions=asRecordLoose(parsed);const entries=managedExtensions?.entries;if(!Array.isArray(entries)){return packages}for(const entry of entries){if(typeof entry!=="object"||entry===null){continue}const record=entry;const sourcePackage=normalizeManagedSourcePackage(record.source?.package);const aliases=[record.source?.input,record.source?.name,sourcePackage].map(value=>normalizeManagedSourcePackage(value)).filter(value=>value!==void 0);const contributions=normalizeExtensionContributionInventory(record.contributions);const identity={aliases:[...new Set(aliases)],...sourcePackage?{package_name:sourcePackage}:{},...contributions?{contributions}:{}};if(typeof record.directory==="string"&&record.directory.trim().length>0){packages.set(`directory:${record.directory.trim()}`,identity)}if(typeof record.name==="string"&&record.name.trim().length>0){packages.set(`name:${record.name.trim()}`,identity)}}}catch{return packages}return packages}function sortCandidates(candidates){return[...candidates].sort((left,right)=>{if(left.manifest.priority!==right.manifest.priority){return left.manifest.priority-right.manifest.priority}const byName=left.manifest.name.localeCompare(right.manifest.name);if(byName!==0){return byName}return left.directory.localeCompare(right.directory)})}function buildEffectiveExtensions(globalCandidates,projectCandidates){const ordered=[...sortCandidates(globalCandidates),...sortCandidates(projectCandidates)];const effective=[];for(const candidate of ordered){const existingIndex=effective.findIndex(entry=>entry.manifest.name===candidate.manifest.name);if(existingIndex>=0){effective.splice(existingIndex,1)}effective.push(candidate)}return effective}async function scanExtensionLayer(layer,extensionsRoot,enabled,disabled,pmMaxVersionExceededMode){const diagnostics=[];const warnings=[];const candidates=[];const directories=await listExtensionDirectories(extensionsRoot);const managedSourcePackages=await readManagedExtensionSourcePackages(extensionsRoot);for(const directory of directories){const scanned=await scanExtensionDirectory(layer,extensionsRoot,directory,enabled,disabled,managedSourcePackages,pmMaxVersionExceededMode);diagnostics.push(scanned.diagnostic);warnings.push(...scanned.warnings);if(scanned.candidate){candidates.push(scanned.candidate)}}return{diagnostics,warnings,candidates}}function emptyExtensionLayerScan(){return{diagnostics:[],warnings:[],candidates:[]}}function buildUnavailableExtensionScan(layer,directory,manifestPath,warning){return{diagnostic:{layer,directory,manifest_path:manifestPath,name:null,version:null,entry:null,priority:null,entry_path:null,enabled:null,status:"warn"},warnings:[warning],candidate:null}}function collectScannedExtensionWarnings(layer,manifest,rawManifest,entryWithinDirectory,entryExists,pmVersionCompatibility,pmMaxVersionCompatibility){const extensionWarnings=formatExtensionManifestSchemaWarnings(layer,manifest,rawManifest);if(Array.isArray(manifest.legacy_capability_aliases)&&manifest.legacy_capability_aliases.length>0){extensionWarnings.push(formatLegacyExtensionCapabilityAliasWarning(layer,manifest.name,manifest.legacy_capability_aliases))}for(const capability of collectUnknownExtensionCapabilities(manifest.capabilities)){extensionWarnings.push(formatUnknownExtensionCapabilityWarning(layer,manifest.name,capability))}if(!entryWithinDirectory){extensionWarnings.push(`extension_entry_outside_extension:${layer}:${manifest.name}`)}else if(!entryExists){extensionWarnings.push(`extension_entry_missing:${layer}:${manifest.name}`)}if(pmVersionCompatibility.warning){extensionWarnings.push(pmVersionCompatibility.warning)}if(pmMaxVersionCompatibility.warning){extensionWarnings.push(pmMaxVersionCompatibility.warning)}return extensionWarnings}async function scanExtensionDirectory(layer,extensionsRoot,directory,enabled,disabled,managedSourcePackages,pmMaxVersionExceededMode){const extensionDir=path.join(extensionsRoot,directory);const manifestPath=path.join(extensionDir,"manifest.json");if(!await pathExists(manifestPath)){return buildUnavailableExtensionScan(layer,directory,manifestPath,`extension_manifest_missing:${layer}:${directory}`)}let manifest;let rawManifest;try{const parsed=JSON.parse(await fs.readFile(manifestPath,"utf8"));rawManifest=asRecordLoose(parsed);manifest=parseExtensionManifestDocument(parsed)}catch{rawManifest=null;manifest=null}if(!manifest||!rawManifest){return buildUnavailableExtensionScan(layer,directory,manifestPath,`extension_manifest_invalid:${layer}:${directory}`)}const entryPath=path.resolve(extensionDir,manifest.entry);const entryWithinDirectoryByPath=isPathWithinDirectory(extensionDir,entryPath);const entryExists=entryWithinDirectoryByPath?await pathExists(entryPath):false;const entryWithinDirectory=entryWithinDirectoryByPath&&entryExists?await isCanonicalPathWithinDirectory(extensionDir,entryPath):entryWithinDirectoryByPath;const enabledForLoad=shouldEnable(manifest.name,enabled,disabled);const pmVersionCompatibility=await evaluatePmMinVersionCompatibility(layer,manifest);const pmMaxVersionCompatibility=await evaluatePmMaxVersionCompatibility(layer,manifest,pmMaxVersionExceededMode);const extensionWarnings=collectScannedExtensionWarnings(layer,manifest,rawManifest,entryWithinDirectory,entryExists,pmVersionCompatibility,pmMaxVersionCompatibility);const extensionReady=entryWithinDirectory&&entryExists&&pmVersionCompatibility.allowed&&pmMaxVersionCompatibility.allowed;const sourceIdentity=managedSourcePackages.get(`directory:${directory}`)??managedSourcePackages.get(`name:${manifest.name}`);return{diagnostic:{layer,directory,manifest_path:manifestPath,name:manifest.name,version:manifest.version,entry:manifest.entry,priority:manifest.priority,entry_path:entryPath,enabled:enabledForLoad,status:extensionReady?"ok":"warn"},warnings:extensionWarnings,candidate:buildReadyExtensionCandidate({layer,directory,manifestPath,entryPath,manifest,sourceIdentity,extensionReady,enabledForLoad})}}async function discoverExtensions(options){const roots=resolveExtensionRoots(options.pmRoot,options.cwd??process.cwd());const configured_enabled=normalizeNames(options.settings.extensions.enabled);const configured_disabled=normalizeNames(options.settings.extensions.disabled);const policy=normalizeExtensionPolicy(options.settings);const serializedPolicy=serializeExtensionPolicy(policy);if(options.noExtensions){return{disabled_by_flag:true,roots,configured_enabled,configured_disabled,discovered:[],effective:[],warnings:[...policy.warnings],policy:serializedPolicy}}const enabled=new Set(configured_enabled);const disabled=new Set(configured_disabled);const globalScan=options.ignoreGlobalExtensions===true?emptyExtensionLayerScan():await scanExtensionLayer("global",roots.global,enabled,disabled,policy.pmMaxVersionExceededMode.global);const projectScan=await scanExtensionLayer("project",roots.project,enabled,disabled,policy.pmMaxVersionExceededMode.project);const policyWarnings=[...policy.warnings];const effectiveCandidates=buildEffectiveExtensions(globalScan.candidates,projectScan.candidates);const effective=[];for(const candidate of effectiveCandidates){const extensionRef={layer:candidate.layer,name:candidate.manifest.name,trusted:candidate.manifest.trusted===true,provenanceVerified:candidate.manifest.provenance?.verified===true,sandboxProfile:candidate.manifest.sandbox_profile,permissions:candidate.manifest.permissions&&typeof candidate.manifest.permissions==="object"?{fs_read:candidate.manifest.permissions.fs_read,fs_write:candidate.manifest.permissions.fs_write,network:candidate.manifest.permissions.network,env_read:candidate.manifest.permissions.env_read,env_write:candidate.manifest.permissions.env_write,process_spawn:candidate.manifest.permissions.process_spawn}:void 0};const extensionDecision=evaluateExtensionPolicyForExtension(policy,extensionRef);if(extensionDecision.warning){policyWarnings.push(extensionDecision.warning)}if(!extensionDecision.allowed){continue}for(const capability of candidate.manifest.capabilities){const capabilityDecision=evaluateExtensionPolicyForCapability(policy,extensionRef,capability);if(capabilityDecision.warning){policyWarnings.push(capabilityDecision.warning)}}effective.push(summarizeCandidate(candidate))}return{disabled_by_flag:false,roots,configured_enabled,configured_disabled,discovered:[...globalScan.diagnostics,...projectScan.diagnostics],effective,warnings:[...new Set([...globalScan.warnings,...projectScan.warnings,...policyWarnings])],policy:serializedPolicy}}function formatUnknownError(error){if(error instanceof Error&&error.message.trim().length>0){return error.message}return String(error)}async function readCurrentPmCliVersion(){try{const packageRoot=resolvePmPackageRootFromModule(import.meta.url,["../../.."]);const raw=await fs.readFile(path.join(packageRoot,"package.json"),"utf8");const parsed=JSON.parse(raw);return typeof parsed.version==="string"&&parsed.version.trim().length>0?parsed.version.trim():null}catch{return null}}function resolveCurrentPmCliVersion(){currentPmCliVersionPromise??=readCurrentPmCliVersion();return currentPmCliVersionPromise}function formatPmVersionCompatibilityWarning(layer,manifest,evaluation){const current=evaluation.current??"unknown";if(evaluation.kind==="pm_min_version"){switch(evaluation.status){case"invalid":return`extension_pm_min_version_invalid:${layer}:${manifest.name}:required=${evaluation.required}`;case"unchecked":return`extension_pm_min_version_unchecked:${layer}:${manifest.name}:required=${evaluation.required}:current=${current}`;case"unmet":return`extension_pm_min_version_unmet:${layer}:${manifest.name}:required=${evaluation.required}:current=${current}`;default:return void 0}}switch(evaluation.status){case"invalid":return`extension_pm_max_version_invalid:${layer}:${manifest.name}:allowed=${evaluation.required}`;case"unchecked":return`extension_pm_max_version_unchecked:${layer}:${manifest.name}:allowed=${evaluation.required}:current=${current}`;case"exceeded_warn":return`extension_pm_max_version_exceeded_warn:${layer}:${manifest.name}:allowed=${evaluation.required}:current=${current}`;case"exceeded":return`extension_pm_max_version_exceeded:${layer}:${manifest.name}:allowed=${evaluation.required}:current=${current}`;default:return void 0}}async function evaluatePmMinVersionCompatibility(layer,manifest){if(manifest.pm_min_version===void 0){return{allowed:true}}const evaluation=evaluatePmMinVersionBound(manifest.pm_min_version,await resolveCurrentPmCliVersion());const warning=formatPmVersionCompatibilityWarning(layer,manifest,evaluation);return warning?{allowed:evaluation.allowed,warning}:{allowed:evaluation.allowed}}async function evaluatePmMaxVersionCompatibility(layer,manifest,exceededMode){if(manifest.pm_max_version===void 0){return{allowed:true}}const evaluation=evaluatePmMaxVersionBound(manifest.pm_max_version,await resolveCurrentPmCliVersion(),exceededMode);const warning=formatPmVersionCompatibilityWarning(layer,manifest,evaluation);return warning?{allowed:evaluation.allowed,warning}:{allowed:evaluation.allowed}}async function fingerprintPath(pathToInspect){try{const stats=await fs.stat(pathToInspect);return`${Math.trunc(stats.mtimeMs)}-${stats.size}`}catch{return"missing"}}async function resolveExtensionImportHref(extension,options){let importEntryPath=extension.entry_path;if(options.module_graph_snapshot_root){importEntryPath=await snapshotExtensionModuleGraph(options.module_graph_snapshot_root,extension)}const baseUrl=new URL(pathToFileURL(importEntryPath).href);const shouldCacheBust=options.cache_bust===true||typeof options.reload_token==="string";if(!shouldCacheBust){return baseUrl.href}const[entryFingerprint,manifestFingerprint]=await Promise.all([fingerprintPath(extension.entry_path),fingerprintPath(extension.manifest_path)]);const reloadToken=options.reload_token??nextExtensionReloadToken();baseUrl.searchParams.set("pm_ext_reload",reloadToken);baseUrl.searchParams.set("pm_ext_entry",entryFingerprint);baseUrl.searchParams.set("pm_ext_manifest",manifestFingerprint);return baseUrl.href}async function loadExtensions(options){const discovery=await discoverExtensions(options);const loaded=[];const failed=[];const warnings=[...discovery.warnings];if(discovery.disabled_by_flag){return{...discovery,warnings,loaded,failed}}const extensionsToLoad=typeof options.extensionFilter==="function"?discovery.effective.filter(options.extensionFilter):discovery.effective;for(const extension of extensionsToLoad){try{const importHref=await resolveExtensionImportHref(extension,options);const module=await import(importHref);loaded.push({...extension,module})}catch(error){warnings.push(`extension_load_failed:${extension.layer}:${extension.name}`);failed.push({layer:extension.layer,name:extension.name,entry_path:extension.entry_path,error:formatUnknownError(error)})}}return{...discovery,warnings,loaded,failed}}const DEFAULT_EXTENSION_DEACTIVATE_TIMEOUT_MS=5e3;const MAX_EXTENSION_DEACTIVATE_TIMEOUT_MS=2147483647;function toActivatableExtension(source){const activate=source.activate;const activatable={activate:activate.bind(source)};if(typeof source.deactivate==="function"){const deactivate=source.deactivate;activatable.deactivate=deactivate.bind(source)}return activatable}function resolveActivatableExtension(module){const activatableRecord=resolveActivatablePropertyRecord(module);return activatableRecord?toActivatableExtension(activatableRecord):null}async function deactivateExtensions(loadResult,activationResult,options={}){const timeoutMs=normalizeExtensionDeactivateTimeout(options?.deactivate_timeout_ms);const failedActivationKeys=new Set((activationResult?.failed??[]).map(entry=>`${entry.layer}:${entry.name}`));const targets=[];for(const extension of loadResult.loaded){if(failedActivationKeys.has(`${extension.layer}:${extension.name}`)){continue}const activatable=resolveActivatableExtension(extension.module);if(!activatable||typeof activatable.deactivate!=="function"){continue}targets.push({extension,deactivate:activatable.deactivate})}const outcomes=await Promise.all(targets.map(async({extension,deactivate})=>{try{await runExtensionDeactivateWithTimeout(deactivate,timeoutMs);return{ok:true}}catch(error){return{ok:false,layer:extension.layer,name:extension.name,error:formatUnknownError(error)}}}));const warnings=[];const failed=[];let deactivated=0;for(const outcome of outcomes){if(outcome.ok){deactivated+=1;continue}warnings.push(`extension_deactivate_failed:${outcome.layer}:${outcome.name}`);failed.push({layer:outcome.layer,name:outcome.name,error:outcome.error})}return{deactivated,warnings,failed}}function normalizeExtensionDeactivateTimeout(rawTimeout){if(typeof rawTimeout!=="number"||rawTimeout<0){return DEFAULT_EXTENSION_DEACTIVATE_TIMEOUT_MS}if(rawTimeout===0||rawTimeout===Infinity){return 0}if(!Number.isFinite(rawTimeout)){return DEFAULT_EXTENSION_DEACTIVATE_TIMEOUT_MS}return Math.min(MAX_EXTENSION_DEACTIVATE_TIMEOUT_MS,Math.max(1,Math.floor(rawTimeout)))}async function runExtensionDeactivateWithTimeout(deactivate,timeoutMs){if(timeoutMs===0){await deactivate();return}let timeoutHandle;try{const deactivatePromise=Promise.resolve().then(()=>deactivate());deactivatePromise.catch(()=>{});await Promise.race([deactivatePromise,new Promise((_,reject)=>{timeoutHandle=setTimeout(()=>{reject(new Error(`extension deactivate timed out after ${timeoutMs}ms`))},timeoutMs);timeoutHandle.unref?.()})])}finally{clearTimeout(timeoutHandle)}}function getDeclaredExtensionCapabilities(extension){if(!Array.isArray(extension.capabilities)){return null}const declared=new Set;for(const capability of extension.capabilities){const normalized=capability.trim().toLowerCase();if(isKnownExtensionCapability(normalized)){declared.add(normalized)}}return declared}function assertExtensionCapability(extension,capability,method){const declared=getDeclaredExtensionCapabilities(extension);if(declared===null){return}if(!declared.has(capability)){throw createRegistrationValidationError(`${method} requires capability '${capability}' in extension manifest capabilities`,{method,registration_index:-1,capability,missing_capability:capability,expected_schema:`"capabilities": [..., "${capability}"]`,received:extension.capabilities,hint:`Add "${capability}" to ${extension.name} manifest capabilities, or remove the ${method} registration call.`})}}function buildExtensionSelfIdentity(extension){return Object.freeze({name:extension.name,layer:extension.layer,version:extension.version,capabilities:Object.freeze((extension.capabilities??[]).filter(capability=>KNOWN_EXTENSION_CAPABILITIES.includes(capability))),pm_min_version:extension.pm_min_version,pm_max_version:extension.pm_max_version,source_package:extension.source_package})}function buildPolicyExtensionRef(extension){return{layer:extension.layer,name:extension.name,trusted:extension.trusted===true,provenanceVerified:extension.provenance?.verified===true,sandboxProfile:extension.sandbox_profile,permissions:extension.permissions&&typeof extension.permissions==="object"?{fs_read:extension.permissions.fs_read,fs_write:extension.permissions.fs_write,network:extension.permissions.network,env_read:extension.permissions.env_read,env_write:extension.permissions.env_write,process_spawn:extension.permissions.process_spawn}:void 0}}class ExtensionApiRegistrar{extension;hooks;#loadedExtension;#extensionRef;#hookRegistry;#commandRegistry;#parserRegistry;#preflightRegistry;#serviceRegistry;#rendererRegistry;#registrationRegistry;#activationWarnings;#activationFailures;#policy;constructor(extension,hooks,commands,parsers,preflight,services,renderers,registrations,activationWarnings,activationFailures,policy){this.#loadedExtension=extension;this.extension=buildExtensionSelfIdentity(extension);this.#extensionRef=buildPolicyExtensionRef(extension);this.#hookRegistry=hooks;this.#commandRegistry=commands;this.#parserRegistry=parsers;this.#preflightRegistry=preflight;this.#serviceRegistry=services;this.#rendererRegistry=renderers;this.#registrationRegistry=registrations;this.#activationWarnings=activationWarnings;this.#activationFailures=activationFailures;this.#policy=policy;this.registerCommand=this.registerCommand.bind(this);this.registerParser=this.registerParser.bind(this);this.registerPreflight=this.registerPreflight.bind(this);this.registerService=this.registerService.bind(this);this.registerFlags=this.registerFlags.bind(this);this.registerItemFields=this.registerItemFields.bind(this);this.registerItemTypes=this.registerItemTypes.bind(this);this.registerRelationshipKinds=this.registerRelationshipKinds.bind(this);this.registerMigration=this.registerMigration.bind(this);this.registerProfile=this.registerProfile.bind(this);this.registerRenderer=this.registerRenderer.bind(this);this.registerImporter=this.registerImporter.bind(this);this.registerExporter=this.registerExporter.bind(this);this.registerSearchProvider=this.registerSearchProvider.bind(this);this.registerVectorStoreAdapter=this.registerVectorStoreAdapter.bind(this);this.registerAssuranceMeasurementProvider=this.registerAssuranceMeasurementProvider.bind(this);this.hooks={beforeCommand:hook=>this.registerBeforeCommand(hook),beforeMutation:hook=>this.registerBeforeMutation(hook),afterCommand:hook=>this.registerAfterCommand(hook),onWrite:hook=>this.registerOnWrite(hook),onRead:hook=>this.registerOnRead(hook),onIndex:hook=>this.registerOnIndex(hook)}}allowRegistration(surface,method,capability,details){const decision=evaluateExtensionPolicyForRegistration(this.#policy,this.#extensionRef,surface,method,capability,details);if(decision.warning){this.#activationWarnings.push(decision.warning)}return decision.allowed}registerCommandTrace(mode,command,expectedSchema,received,hint){return{method:"registerCommand",registration_index:mode==="override"?this.#commandRegistry.overrides.length:this.#commandRegistry.handlers.length,command,expected_schema:expectedSchema,received:sanitizeRegistrationValue(received),hint}}registerCommandOverride(command,override){const normalizedCommand=normalizeCommandName(command);if(normalizedCommand.length===0){throw createRegistrationValidationError("registerCommand requires a non-empty command name",this.registerCommandTrace("override",command,'registerCommand("<command>", (context) => unknown)',command,"Provide a non-empty command path as the first argument."))}if(typeof override!=="function"){const trace=this.registerCommandTrace("override",normalizedCommand,'registerCommand("<command>", (context) => unknown)',override,"Provide a function as the second registerCommand argument.");throw createRegistrationValidationError(`registerCommand requires an override function when command name is provided (command="${normalizedCommand}", registration_index=${trace.registration_index})`,trace)}if(!this.allowRegistration("commands.override","registerCommand","commands",{command:normalizedCommand})){return}this.#commandRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:normalizedCommand,run:override})}resolveCommandDefinitionRunHandler(definition,normalizedCommand){const runHandler=typeof definition.run==="function"?definition.run:void 0;const legacyHandler=typeof definition.handler==="function"?definition.handler:void 0;if(!runHandler&&legacyHandler){this.#activationWarnings.push(`extension_command_definition_legacy_handler_alias:${this.#loadedExtension.layer}:${this.#loadedExtension.name}:${normalizedCommand}`)}return runHandler??legacyHandler}registerCommandDefinition(definition){if(typeof definition!=="object"||definition===null){throw createRegistrationValidationError("registerCommand requires a command definition object",this.registerCommandTrace("definition",void 0,"{ name: string; run: (context) => unknown; }",definition,'Use registerCommand({ name: "command path", run: (context) => ... }).'))}if(typeof definition.name!=="string"){throw createRegistrationValidationError("registerCommand requires a command definition name",this.registerCommandTrace("definition",void 0,"{ name: string; run: (context) => unknown; }",definition,"Set command definition.name to a non-empty string command path."))}const normalizedCommand=normalizeCommandName(definition.name);if(normalizedCommand.length===0){throw createRegistrationValidationError("registerCommand requires a non-empty command definition name",this.registerCommandTrace("definition",definition.name,"{ name: string; run: (context) => unknown; }",definition,"Ensure command definition.name contains a non-empty command path."))}const resolvedHandler=this.resolveCommandDefinitionRunHandler(definition,normalizedCommand);if(typeof resolvedHandler!=="function"){const trace=this.registerCommandTrace("definition",normalizedCommand,"{ name: string; run: (context) => unknown; }",resolvedHandler,"Define command definition.run as a function.");throw createRegistrationValidationError(`registerCommand requires a command definition run handler (command="${normalizedCommand}", registration_index=${trace.registration_index})`,trace)}try{assertCommandDefinitionMetadataStrings(definition);const action=resolveCommandDefinitionAction(normalizedCommand,definition.action);if(!this.allowRegistration("commands.handler","registerCommand","commands",{command:normalizedCommand,action})){return}const description=definition.description?.trim();const intent=definition.intent?.trim();const examples=normalizeOptionalStringArrayField("registerCommand definition.examples",definition.examples);const failureHints=normalizeOptionalStringArrayField("registerCommand definition.failure_hints",definition.failure_hints);const argumentsDefinition=normalizeCommandDefinitionArguments(definition.arguments);if(definition.flags!==void 0){assertExtensionCapability(this.#loadedExtension,"schema","registerCommand flags");if(this.allowRegistration("schema.flags","registerCommand flags","schema")){validateFlagDefinitions(definition.flags);this.#registrationRegistry.flags.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,target_command:normalizedCommand,flags:normalizeFlagDefinitions("registerCommand definition.flags",definition.flags)})}}const registration={layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,source_package:this.#loadedExtension.source_package,command:normalizedCommand,action,examples,failure_hints:failureHints,arguments:argumentsDefinition,tier:definition.tier??"standard",family:definition.family??"extensions"};if(description){registration.description=description}if(intent){registration.intent=intent}this.#registrationRegistry.commands.push(registration)}catch(error){const reason=formatUnknownError(error);const trace=this.registerCommandTrace("definition",normalizedCommand,"{ name: string; run: (context) => unknown; action?: string; arguments?: object[]; flags?: object[]; }",definition,reason);const validationError=createRegistrationValidationError(`registerCommand definition metadata invalid (command="${normalizedCommand}", registration_index=${trace.registration_index}): ${reason}`,trace);this.#activationWarnings.push(`extension_command_quarantined:${this.#loadedExtension.layer}:${this.#loadedExtension.name}:${normalizedCommand}`);this.#activationFailures.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,entry_path:this.#loadedExtension.entry_path,error:validationError.message,trace});return}this.#commandRegistry.handlers.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:normalizedCommand,run:resolvedHandler})}registerCommand(commandOrDefinition,override){assertExtensionCapability(this.#loadedExtension,"commands","registerCommand");if(typeof commandOrDefinition==="string"){this.registerCommandOverride(commandOrDefinition,override);return}this.registerCommandDefinition(commandOrDefinition)}registerParser(command,override){assertExtensionCapability(this.#loadedExtension,"parser","registerParser");if(!this.allowRegistration("parser.override","registerParser","parser")){return}const normalizedCommand=normalizeCommandName(assertNonEmptyRegistrationString("registerParser command",command));assertRegistrationFunction("registerParser override",override);this.#parserRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:normalizedCommand,run:override})}registerPreflight(override){assertExtensionCapability(this.#loadedExtension,"preflight","registerPreflight");if(!this.allowRegistration("preflight.override","registerPreflight","preflight")){return}const normalized=normalizePreflightOverride(override);this.#preflightRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,...normalized})}registerService(service,override,ownership={}){assertExtensionCapability(this.#loadedExtension,"services","registerService");const normalizedService=String(service).trim().toLowerCase();if(!isExtensionServiceName(normalizedService)){throw new TypeError(`registerService service must be one of: ${KNOWN_EXTENSION_SERVICE_NAMES.join(", ")}`)}if(!this.allowRegistration("services.override","registerService","services",{service:normalizedService})){return}assertRegistrationFunction("registerService override",override);this.#serviceRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,service:normalizedService,run:override,...normalizeServiceOverrideOwnership(ownership)?{passThrough:true}:{}})}registerRenderer(format,renderer,ownership={}){assertExtensionCapability(this.#loadedExtension,"renderers","registerRenderer");if(!this.allowRegistration("renderers.override","registerRenderer","renderers")){return}if(typeof renderer!=="function"){throw new TypeError("registerRenderer requires a renderer function")}const normalizedFormat=String(format).trim().toLowerCase();if(!isOutputRendererFormat(normalizedFormat)){throw new Error(`registerRenderer format must be toon|json, received: ${String(format)}`)}if(ownership.resultDiscriminator!==void 0&&typeof ownership.resultDiscriminator!=="function"){throw new TypeError("registerRenderer ownership.resultDiscriminator must be a function when provided")}const commands=[...new Set((ownership.commands??[]).map(command=>{if(typeof command!=="string"||command.trim().length===0){throw new TypeError("registerRenderer ownership.commands must contain non-empty command paths")}return normalizeCommandName(command)}))];this.#rendererRegistry.overrides.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,format:normalizedFormat,run:renderer,commands,...ownership.resultDiscriminator?{resultDiscriminator:ownership.resultDiscriminator}:{}})}registerFlags(targetCommand,flags){assertExtensionCapability(this.#loadedExtension,"schema","registerFlags");if(!this.allowRegistration("schema.flags","registerFlags","schema")){return}const normalizedTargetCommand=normalizeCommandName(assertNonEmptyRegistrationString("registerFlags targetCommand",targetCommand));validateFlagDefinitions(flags);const normalizedFlags=normalizeFlagDefinitions("registerFlags flags",flags);if(normalizedFlags.length===0){throw new TypeError("registerFlags requires at least one flag definition")}this.#registrationRegistry.flags.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,target_command:normalizedTargetCommand,flags:normalizedFlags})}registerItemFields(fields){assertExtensionCapability(this.#loadedExtension,"schema","registerItemFields");if(!this.allowRegistration("schema.itemfields","registerItemFields","schema")){return}validateItemFieldDefinitions(fields);const normalizedFields=normalizeRegistrationRecordList("registerItemFields fields",fields);if(normalizedFields.length===0){throw new TypeError("registerItemFields requires at least one field definition")}this.#registrationRegistry.item_fields.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,fields:normalizedFields})}registerItemTypes(types){assertExtensionCapability(this.#loadedExtension,"schema","registerItemTypes");if(!this.allowRegistration("schema.itemtypes","registerItemTypes","schema")){return}validateItemTypeDefinitions(types);const normalizedTypes=normalizeRegistrationRecordList("registerItemTypes types",types);if(normalizedTypes.length===0){throw new TypeError("registerItemTypes requires at least one type definition")}this.#registrationRegistry.item_types.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,types:normalizedTypes})}registerRelationshipKinds(definitions){assertExtensionCapability(this.#loadedExtension,"schema","registerRelationshipKinds");if(!this.allowRegistration("schema.relationshipkinds","registerRelationshipKinds","schema")){return}if(!Array.isArray(definitions)){throw new TypeError("registerRelationshipKinds definitions requires an array of object definitions")}if(definitions.length===0){throw new TypeError("registerRelationshipKinds requires at least one definition")}const registry=createRelationshipKindRegistry();for(const registration of this.#registrationRegistry.relationship_kinds){for(const definition of registration.definitions){registry.register(definition)}}const validated=definitions.map(definition=>{registry.register(definition);return registry.require(definition.kind)});this.#registrationRegistry.relationship_kinds.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,definitions:validated})}registerMigration(definition){assertExtensionCapability(this.#loadedExtension,"schema","registerMigration");if(!this.allowRegistration("schema.migrations","registerMigration","schema")){return}validateMigrationDefinition(definition);const runtimeDefinition=normalizeRuntimeRegistrationRecord("registerMigration definition",definition);this.#registrationRegistry.migrations.push(attachRuntimeDefinition({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,definition:normalizeRegistrationRecord("registerMigration definition",definition)},runtimeDefinition))}registerProfile(profile){assertExtensionCapability(this.#loadedExtension,"schema","registerProfile");if(!this.allowRegistration("schema.profiles","registerProfile","schema")){return}const snapshot=cloneRuntimeRegistrationValue(profile);validateProjectProfileDefinition(snapshot);this.#registrationRegistry.profiles.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,profile:applyProjectProfileDefaults(snapshot)})}registerImportExportCommandFlags(method,commandPath,resolvedOptions){if(resolvedOptions.flags===void 0){return}assertExtensionCapability(this.#loadedExtension,"schema",`${method} options.flags`);if(!this.allowRegistration("schema.flags",`${method} options.flags`,"schema")){return}validateFlagDefinitions(resolvedOptions.flags);this.#registrationRegistry.flags.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,target_command:commandPath,flags:normalizeFlagDefinitions(`${method} options.flags`,resolvedOptions.flags)})}applyImportExportCommandMetadata(method,commandPath,options){if(options!==void 0&&(typeof options!=="object"||options===null||Array.isArray(options))){throw new TypeError(`${method} options must be an object when provided`)}const defaultDescription=`${method==="registerImporter"?"Import":"Export"} items with the registered extension adapter.`;const defaultArguments=[{name:"file",required:false,description:"Optional input or output file path."}];const resolvedOptions={...options,description:options?.description??defaultDescription,arguments:options?.arguments??defaultArguments};const output=resolveImportExportArtifactOutput(method,resolvedOptions,options?.description!==void 0);assertOptionalStringField(`${method} options.action`,resolvedOptions.action);assertOptionalStringField(`${method} options.description`,resolvedOptions.description);assertOptionalStringField(`${method} options.intent`,resolvedOptions.intent);const action=resolveCommandDefinitionAction(commandPath,resolvedOptions.action);const examples=normalizeOptionalStringArrayField(`${method} options.examples`,resolvedOptions.examples);const failureHints=normalizeOptionalStringArrayField(`${method} options.failure_hints`,resolvedOptions.failure_hints);const argumentsDefinition=normalizeCommandDefinitionArguments(resolvedOptions.arguments);this.registerImportExportCommandFlags(method,commandPath,resolvedOptions);const registration={layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,source_package:this.#loadedExtension.source_package,command:commandPath,action,examples,failure_hints:failureHints,arguments:argumentsDefinition};const description=resolvedOptions.description?.trim();if(description){registration.description=description}const intent=resolvedOptions.intent?.trim();if(intent){registration.intent=intent}this.#registrationRegistry.commands.push(registration);return output}registerImporter(name,importer,options){assertExtensionCapability(this.#loadedExtension,"importers","registerImporter");if(!this.allowRegistration("importers.importer","registerImporter","importers")){return}const normalizedName=normalizeRegistrationName(assertNonEmptyRegistrationString("registerImporter name",name));assertRegistrationFunction("registerImporter importer",importer);const commandPath=toRegistrationCommandPath(normalizedName,"import");this.applyImportExportCommandMetadata("registerImporter",commandPath,options);this.#registrationRegistry.importers.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,importer:normalizedName});this.#commandRegistry.handlers.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:commandPath,run:async context=>importer(buildImportExportContext(context,normalizedName,"import"))})}registerExporter(name,exporter,options){assertExtensionCapability(this.#loadedExtension,"importers","registerExporter");if(!this.allowRegistration("importers.exporter","registerExporter","importers")){return}const normalizedName=normalizeRegistrationName(assertNonEmptyRegistrationString("registerExporter name",name));assertRegistrationFunction("registerExporter exporter",exporter);const commandPath=toRegistrationCommandPath(normalizedName,"export");const output=this.applyImportExportCommandMetadata("registerExporter",commandPath,options);this.#registrationRegistry.exporters.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,exporter:normalizedName,...output===void 0?{}:{output}});this.#commandRegistry.handlers.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,command:commandPath,run:async context=>{const result=await exporter(buildImportExportContext(context,normalizedName,"export"));return output?.receipt==="suppress"&&!isHostOutputSuppressed(result)?suppressHostOutput(result):result}})}registerSearchProvider(provider){assertExtensionCapability(this.#loadedExtension,"search","registerSearchProvider");if(!this.allowRegistration("search.provider","registerSearchProvider","search")){return}const runtimeDefinition=normalizeRuntimeRegistrationRecord("registerSearchProvider provider",provider);this.#registrationRegistry.search_providers.push(attachRuntimeDefinition({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,definition:normalizeRegistrationRecord("registerSearchProvider provider",provider)},runtimeDefinition))}registerVectorStoreAdapter(adapter){assertExtensionCapability(this.#loadedExtension,"search","registerVectorStoreAdapter");if(!this.allowRegistration("search.vectorstore","registerVectorStoreAdapter","search")){return}const runtimeDefinition=normalizeRuntimeRegistrationRecord("registerVectorStoreAdapter adapter",adapter);this.#registrationRegistry.vector_store_adapters.push(attachRuntimeDefinition({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,definition:normalizeRegistrationRecord("registerVectorStoreAdapter adapter",adapter)},runtimeDefinition))}registerAssuranceMeasurementProvider(provider){assertExtensionCapability(this.#loadedExtension,"services","registerAssuranceMeasurementProvider");if(!this.allowRegistration("services.assuranceprovider","registerAssuranceMeasurementProvider","services")){return}validateAssuranceMeasurementProviderDefinition(provider);if(provider.network&&this.#loadedExtension.permissions?.network!==true){throw new TypeError("registerAssuranceMeasurementProvider network provider requires permissions.network=true")}const runtimeDefinition=normalizeRuntimeRegistrationRecord("registerAssuranceMeasurementProvider provider",provider);this.#registrationRegistry.assurance_providers.push(attachRuntimeDefinition({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,network_permission:this.#loadedExtension.permissions?.network===true,definition:normalizeRegistrationRecord("registerAssuranceMeasurementProvider provider",provider)},runtimeDefinition))}registerBeforeCommand(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.beforeCommand");if(!this.allowRegistration("hooks.beforecommand","api.hooks.beforeCommand","hooks"))return;assertHookHandler("beforeCommand",hook);this.#hookRegistry.beforeCommand.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerBeforeMutation(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.beforeMutation");if(!this.allowRegistration("hooks.beforemutation","api.hooks.beforeMutation","hooks"))return;assertHookHandler("beforeMutation",hook);this.#hookRegistry.beforeMutation.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerAfterCommand(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.afterCommand");if(!this.allowRegistration("hooks.aftercommand","api.hooks.afterCommand","hooks"))return;assertHookHandler("afterCommand",hook);this.#hookRegistry.afterCommand.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerOnWrite(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.onWrite");if(!this.allowRegistration("hooks.onwrite","api.hooks.onWrite","hooks"))return;assertHookHandler("onWrite",hook);this.#hookRegistry.onWrite.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerOnRead(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.onRead");if(!this.allowRegistration("hooks.onread","api.hooks.onRead","hooks"))return;assertHookHandler("onRead",hook);this.#hookRegistry.onRead.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}registerOnIndex(hook){assertExtensionCapability(this.#loadedExtension,"hooks","api.hooks.onIndex");if(!this.allowRegistration("hooks.onindex","api.hooks.onIndex","hooks"))return;assertHookHandler("onIndex",hook);this.#hookRegistry.onIndex.push({layer:this.#loadedExtension.layer,name:this.#loadedExtension.name,run:hook})}}function createExtensionApi(extension,hooks,commands,parsers,preflight,services,renderers,registrations,activationWarnings,activationFailures,policy){return new ExtensionApiRegistrar(extension,hooks,commands,parsers,preflight,services,renderers,registrations,activationWarnings,activationFailures,policy)}function getRegistrationCounts(registrations){const commandCount=registrations.commands.length;const flagCount=registrations.flags.reduce((total,entry)=>total+entry.flags.length,0);const itemFieldCount=registrations.item_fields.reduce((total,entry)=>total+entry.fields.length,0);const itemTypeCount=registrations.item_types.reduce((total,entry)=>total+entry.types.length,0);const relationshipKindCount=(registrations.relationship_kinds??[]).reduce((total,entry)=>total+entry.definitions.length,0);return{commands:commandCount,flags:flagCount,item_fields:itemFieldCount,item_types:itemTypeCount,...relationshipKindCount>0?{relationship_kinds:relationshipKindCount}:{},migrations:registrations.migrations.length,profiles:registrations.profiles.length,importers:registrations.importers.length,exporters:registrations.exporters.length,search_providers:registrations.search_providers.length,vector_store_adapters:registrations.vector_store_adapters.length,...(registrations.assurance_providers?.length??0)>0?{assurance_providers:registrations.assurance_providers.length}:{}}}function collectCommandCollisionWarnings(commands){const warnings=[];const collectByCommand=(entries,codePrefix)=>{const grouped=new Map;for(const entry of entries){const bucket=grouped.get(entry.command)??[];bucket.push(entry);grouped.set(entry.command,bucket)}for(const command of[...grouped.keys()].sort((left,right)=>left.localeCompare(right))){const bucket=grouped.get(command);if(bucket.length<=1){continue}const winner=bucket[bucket.length-1];for(const displaced of bucket.slice(0,-1)){warnings.push(`${codePrefix}:${command}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`)}}};collectByCommand(commands.handlers,"extension_command_handler_collision");collectByCommand(commands.overrides,"extension_command_override_collision");const handlerCommands=new Set(commands.handlers.map(entry=>entry.command));const overlapCommands=[...new Set(commands.overrides.map(entry=>entry.command))].filter(command=>handlerCommands.has(command));overlapCommands.sort((left,right)=>left.localeCompare(right));for(const command of overlapCommands){const handlers=commands.handlers.filter(entry=>entry.command===command);const overrides=commands.overrides.filter(entry=>entry.command===command);for(const override of overrides){for(const handler of handlers){warnings.push(`extension_command_override_handler_overlap:${command}:${override.layer}:${override.name}:${handler.layer}:${handler.name}`)}}}return warnings}function collectRendererCollisionWarnings(renderers){const grouped=new Map;for(const entry of renderers.overrides){const bucket=grouped.get(entry.format)??[];bucket.push(entry);grouped.set(entry.format,bucket)}const warnings=[];for(const format of[...grouped.keys()].sort((left,right)=>left.localeCompare(right))){const bucket=grouped.get(format);if(bucket.length<=1){continue}const winner=bucket[bucket.length-1];for(const displaced of bucket.slice(0,-1)){if(winner.commands?.length&&displaced.commands?.length&&!displaced.commands.some(command=>winner.commands?.includes(command))){continue}warnings.push(`extension_renderer_collision:${format}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`)}}return warnings}function collectParserCollisionWarnings(parsers){const warnings=[];const grouped=new Map;for(const entry of parsers.overrides){const bucket=grouped.get(entry.command)??[];bucket.push(entry);grouped.set(entry.command,bucket)}for(const command of[...grouped.keys()].sort((left,right)=>left.localeCompare(right))){const bucket=grouped.get(command);if(bucket.length<=1){continue}const winner=bucket[bucket.length-1];for(const displaced of bucket.slice(0,-1)){warnings.push(`extension_parser_override_collision:${command}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`)}}return warnings}const CHAINED_SERVICE_NAMES=new Set(["output_format"]);function collectServiceCollisionWarnings(services){const warnings=[];const grouped=new Map;for(const entry of services.overrides){const bucket=grouped.get(entry.service)??[];bucket.push(entry);grouped.set(entry.service,bucket)}for(const service of[...grouped.keys()].sort((left,right)=>left.localeCompare(right))){const bucket=grouped.get(service);if(bucket.length<=1){continue}if(CHAINED_SERVICE_NAMES.has(service)){continue}const winner=bucket[bucket.length-1];for(const displaced of bucket.slice(0,-1)){warnings.push(`extension_service_override_collision:${service}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`)}}return warnings}async function activateExtensions(loadResult){const policy=hydrateExtensionPolicy(loadResult.policy??DEFAULT_EXTENSION_POLICY);const hooks=createEmptyExtensionHookRegistry();const commands=createEmptyExtensionCommandRegistry();const parsers=createEmptyExtensionParserRegistry();const preflight=createEmptyExtensionPreflightRegistry();const services=createEmptyExtensionServiceRegistry();const renderers=createEmptyExtensionRendererRegistry();const registrations=createEmptyExtensionRegistrationRegistry();const failed=[];const warnings=[];for(const extension of loadResult.loaded){const activatable=resolveActivatableExtension(extension.module);if(!activatable){continue}const failedBeforeActivation=failed.length;const rollbackPartialActivation=captureExtensionActivationRollback({hooks,commands,parsers,preflight,services,renderers,registrations});try{await activatable.activate(createExtensionApi(extension,hooks,commands,parsers,preflight,services,renderers,registrations,warnings,failed,policy));if(failed.length>failedBeforeActivation){rollbackPartialActivation();warnings.push(`extension_activation_rolled_back:${extension.layer}:${extension.name}`)}}catch(error){rollbackPartialActivation();warnings.push(`extension_activate_failed:${extension.layer}:${extension.name}`);const trace=extractRegistrationValidationTrace(error);failed.push({layer:extension.layer,name:extension.name,entry_path:extension.entry_path,error:formatUnknownError(error),trace})}}const collisionWarnings=[...collectCommandCollisionWarnings(commands),...collectParserCollisionWarnings(parsers),...collectPreflightCollisionWarnings(preflight),...collectServiceCollisionWarnings(services),...collectRendererCollisionWarnings(renderers)];const mergedWarnings=[...new Set([...warnings,...collisionWarnings])];return{hooks,commands,parsers,preflight,services,renderers,registrations,failed,warnings:mergedWarnings,hook_counts:{before_command:hooks.beforeCommand.length,before_mutation:hooks.beforeMutation.length,after_command:hooks.afterCommand.length,on_write:hooks.onWrite.length,on_read:hooks.onRead.length,on_index:hooks.onIndex.length},command_override_count:commands.overrides.length,command_handler_count:commands.handlers.length,parser_override_count:parsers.overrides.length,preflight_override_count:preflight.overrides.length,service_override_count:services.overrides.length,renderer_override_count:renderers.overrides.length,registration_counts:getRegistrationCounts(registrations)}}const _testOnlyLoader={assertFlagValueTypeAndDefault,assertOptionalStringField,compareComparableVersions,collectCommandCollisionWarnings,collectParserCollisionWarnings,collectRendererCollisionWarnings,collectServiceCollisionWarnings,createExtensionApi,createRegistrationValidationError,evaluatePmMaxVersionCompatibility,evaluatePmMinVersionCompatibility,extractRegistrationValidationTrace,fingerprintPath,getRegistrationCounts,normalizeCommandDefinitionArguments,normalizeExtensionDeactivateTimeout,normalizeOptionalStringArrayField,normalizeRegistrationRecord,normalizeRegistrationRecordList,normalizeRuntimeRegistrationRecord,parseComparableVersion,parseManifest:parseExtensionManifestDocument,readCurrentPmCliVersion,readManagedExtensionSourcePackages:async extensionsRoot=>new Map([...await readManagedExtensionSourcePackages(extensionsRoot)].filter(entry=>typeof entry[1].package_name==="string").map(([key,identity])=>[key,identity.package_name])),resolveExtensionImportHref,resolveCurrentPmCliVersion,resolveCommandDefinitionAction,sanitizeRegistrationValue,validateItemFieldDefinitions,resetCurrentPmCliVersionCacheForTest:()=>{currentPmCliVersionPromise=null}};export{DEFAULT_EXTENSION_PRIORITY,_testOnlyLoader,activateExtensions,createEmptyExtensionCommandRegistry2 as createEmptyExtensionCommandRegistry,createEmptyExtensionHookRegistry2 as createEmptyExtensionHookRegistry,createEmptyExtensionParserRegistry2 as createEmptyExtensionParserRegistry,createEmptyExtensionPreflightRegistry2 as createEmptyExtensionPreflightRegistry,createEmptyExtensionRegistrationRegistry2 as createEmptyExtensionRegistrationRegistry,createEmptyExtensionRendererRegistry2 as createEmptyExtensionRendererRegistry,createEmptyExtensionServiceRegistry2 as createEmptyExtensionServiceRegistry,deactivateExtensions,discoverExtensions,isCanonicalPathWithinDirectory,loadExtensions,nextExtensionReloadToken,parseExtensionManifestDocument2 as parseExtensionManifestDocument,parseLegacyExtensionCapabilityAliasWarning,parseUnknownExtensionCapabilityWarning,resolveExtensionRoots,runAfterCommandHooks,runBeforeCommandHooks,runBeforeMutationHooks,runCommandHandler,runCommandOverride,runOnIndexHooks,runOnReadHooks,runOnWriteHooks,runParserOverride,runPreflightOverride,runRendererOverride,runServiceOverride,runServiceOverrideSync};
|
|
2
2
|
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ExtensionManifest } from "./extension-types.js";
|
|
2
|
+
/** Fallback extension priority used when callers do not provide an override. */
|
|
3
|
+
export declare const DEFAULT_EXTENSION_PRIORITY = 100;
|
|
4
|
+
/** Parse and normalize one complete on-disk extension manifest contract. */
|
|
5
|
+
export declare function parseExtensionManifestDocument(raw: unknown): ExtensionManifest | null;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!(function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=new e.Error().stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1c944ddd-e05b-5d8c-bdc5-7bc9677fa5d1")}catch(e2){}})();import{asRecordLoose}from"../shared/primitives.js";import{normalizeExtensionContributionInventory}from"./contribution-inventory.js";import{normalizeManifestCapabilities}from"./extension-capability-aliases.js";import{normalizePolicySandboxProfile}from"./extension-policy.js";import{normalizeCommandName}from"./extension-runtime-helpers.js";const DEFAULT_EXTENSION_PRIORITY=100;function parseOptionalManifestString(candidate,field){const value=candidate[field];if(value===void 0||value===null){return void 0}if(typeof value!=="string"||value.trim().length===0){return null}return value.trim()}function parseManifestEngines(value){if(value===void 0||value===null){return void 0}const enginesRecord=asRecordLoose(value);if(!enginesRecord){return null}const engines={};for(const key of Object.keys(enginesRecord).sort((left,right)=>left.localeCompare(right))){if(key.trim().length===0){return null}const engineValue=enginesRecord[key];if(typeof engineValue!=="string"||engineValue.trim().length===0){return null}engines[key.trim()]=engineValue.trim()}return Object.keys(engines).length>0?engines:void 0}function parseRequiredManifestString(candidate,field){const value=candidate[field];if(typeof value!=="string"||value.trim().length===0){return null}return value.trim()}function parseOptionalIntegerValue(value){if(value===void 0||value===null){return void 0}if(typeof value!=="number"||!Number.isInteger(value)){return null}return value}function parseOptionalBooleanValue(value){if(value===void 0||value===null){return void 0}if(typeof value!=="boolean"){return null}return value}function parseManifestPriority(candidate){const value=parseOptionalIntegerValue(candidate.priority);return value===void 0?DEFAULT_EXTENSION_PRIORITY:value}function parseManifestSandboxProfile(candidate){const value=candidate.sandbox_profile;if(value===void 0||value===null){return void 0}if(typeof value!=="string"){return null}const normalizedProfile=normalizePolicySandboxProfile(value);if(normalizedProfile!==value.trim().toLowerCase()){return null}return normalizedProfile}function optionalTrimmedString(value){return typeof value==="string"&&value.trim().length>0?value.trim():void 0}function parseManifestProvenance(value){if(value===void 0||value===null){return void 0}const provenanceRecord=asRecordLoose(value);if(!provenanceRecord){return null}const source=optionalTrimmedString(provenanceRecord.source);const signature=optionalTrimmedString(provenanceRecord.signature);const attestation=optionalTrimmedString(provenanceRecord.attestation);const verified=provenanceRecord.verified===void 0||provenanceRecord.verified===null?void 0:typeof provenanceRecord.verified==="boolean"?provenanceRecord.verified:null;if(verified===null){return null}return{...source?{source}:{},...signature?{signature}:{},...attestation?{attestation}:{},...typeof verified==="boolean"?{verified}:{}}}function parseManifestPermissions(value){if(value===void 0||value===null){return void 0}const permissionsRecord=asRecordLoose(value);if(!permissionsRecord){return null}const fsRead=parseOptionalBooleanValue(permissionsRecord.fs_read);const fsWrite=parseOptionalBooleanValue(permissionsRecord.fs_write);const network=parseOptionalBooleanValue(permissionsRecord.network);const envRead=parseOptionalBooleanValue(permissionsRecord.env_read);const envWrite=parseOptionalBooleanValue(permissionsRecord.env_write);const processSpawn=parseOptionalBooleanValue(permissionsRecord.process_spawn);if([fsRead,fsWrite,network,envRead,envWrite,processSpawn].includes(null)){return null}return{...typeof fsRead==="boolean"?{fs_read:fsRead}:{},...typeof fsWrite==="boolean"?{fs_write:fsWrite}:{},...typeof network==="boolean"?{network}:{},...typeof envRead==="boolean"?{env_read:envRead}:{},...typeof envWrite==="boolean"?{env_write:envWrite}:{},...typeof processSpawn==="boolean"?{process_spawn:processSpawn}:{}}}function parseManifestCapabilities(value){if(value===void 0||value===null){return{capabilities:[],legacy_aliases:[]}}if(!Array.isArray(value)||value.some(entry=>typeof entry!=="string")){return null}const normalizedCapabilities=normalizeManifestCapabilities(value);return{capabilities:normalizedCapabilities.capabilities,legacy_aliases:normalizedCapabilities.legacy_aliases}}function parseManifestActivation(value){if(value===void 0||value===null){return void 0}const activationRecord=asRecordLoose(value);if(!activationRecord){return null}const rawCommands=activationRecord.commands;if(rawCommands===void 0||rawCommands===null){return void 0}if(!Array.isArray(rawCommands)||rawCommands.some(entry=>typeof entry!=="string")){return null}const commands=[...new Set(rawCommands.map(entry=>normalizeCommandName(entry)).filter(entry=>entry.length>0))].sort((left,right)=>left.localeCompare(right));return commands.length>0?{commands}:void 0}function parseManifestMetadata(candidate){const manifestVersion=parseOptionalIntegerValue(candidate.manifest_version);if(manifestVersion===null){return null}const pmMinVersion=parseOptionalManifestString(candidate,"pm_min_version");if(pmMinVersion===null){return null}const pmMaxVersion=parseOptionalManifestString(candidate,"pm_max_version");if(pmMaxVersion===null){return null}const engines=parseManifestEngines(candidate.engines);if(engines===null){return null}const trusted=parseOptionalBooleanValue(candidate.trusted);if(trusted===null){return null}const sandboxProfile=parseManifestSandboxProfile(candidate);if(sandboxProfile===null){return null}const provenance=parseManifestProvenance(candidate.provenance);if(provenance===null){return null}const permissions=parseManifestPermissions(candidate.permissions);if(permissions===null){return null}const capabilities=parseManifestCapabilities(candidate.capabilities);if(capabilities===null){return null}const activation=parseManifestActivation(candidate.activation);if(activation===null){return null}const contributions=normalizeExtensionContributionInventory(candidate.contributions);if(contributions===null){return null}return{manifest_version:manifestVersion,pm_min_version:pmMinVersion,pm_max_version:pmMaxVersion,engines,trusted,sandbox_profile:sandboxProfile,provenance,permissions,capabilities:capabilities.capabilities,legacy_capability_aliases:capabilities.legacy_aliases,activation,contributions}}function parseExtensionManifestDocument(raw){if(typeof raw!=="object"||raw===null){return null}const candidate=raw;const name=parseRequiredManifestString(candidate,"name");if(name===null){return null}const version=parseRequiredManifestString(candidate,"version");if(version===null){return null}const entry=parseRequiredManifestString(candidate,"entry");if(entry===null){return null}const priority=parseManifestPriority(candidate);if(priority===null){return null}const metadata=parseManifestMetadata(candidate);if(metadata===null){return null}return{name,version,entry,priority,manifest_version:metadata.manifest_version,pm_min_version:metadata.pm_min_version,pm_max_version:metadata.pm_max_version,engines:metadata.engines,trusted:metadata.trusted,provenance:metadata.provenance,sandbox_profile:metadata.sandbox_profile,permissions:metadata.permissions,activation:metadata.activation,contributions:metadata.contributions,capabilities:metadata.capabilities,legacy_capability_aliases:metadata.legacy_capability_aliases.length>0?metadata.legacy_capability_aliases:void 0}}export{DEFAULT_EXTENSION_PRIORITY,parseExtensionManifestDocument};
|
|
2
|
+
//# sourceMappingURL=manifest-parser.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/extensions/registration-contracts
|
|
3
|
+
* Validates contributed command, flag, schema and profile definitions before registration.
|
|
4
|
+
*/
|
|
5
|
+
import type { ProjectProfileDefinition } from "../profile/profile-presets.js";
|
|
6
|
+
import { type ExtensionCommandArgumentDefinition, type FlagDefinition } from "./extension-types.js";
|
|
7
|
+
/** Normalize registration records and expand the repeatable alias into the canonical list flag property. */
|
|
8
|
+
declare function normalizeFlagDefinitions(name: string, value: unknown): FlagDefinition[];
|
|
9
|
+
/** Derive an action from the command path or reject an invalid explicit action before registration. */
|
|
10
|
+
declare function resolveCommandDefinitionAction(commandPath: string, action: unknown): string;
|
|
11
|
+
/** Validate positional argument records and enforce that at most one variadic argument appears last. */
|
|
12
|
+
declare function normalizeCommandDefinitionArguments(value: unknown): ExtensionCommandArgumentDefinition[];
|
|
13
|
+
/** Reject unknown flag properties, invalid tokens, inconsistent repeatability and defaults incompatible with the declared value type. */
|
|
14
|
+
declare function validateFlagDefinitions(flags: unknown): void;
|
|
15
|
+
/** Reject a declared `value_type`/`type` that is not a known flag value kind, and a `default` whose value(s) would not cleanly coerce under that kind — so the typed-flag contract is enforced at registration instead of silently leaving an untyped value to surface at use time. */
|
|
16
|
+
declare function assertFlagValueTypeAndDefault(label: string, record: Record<string, unknown>): void;
|
|
17
|
+
/** Validate custom field names and types, including typo guidance, before fields enter the runtime schema. */
|
|
18
|
+
declare function validateItemFieldDefinitions(fields: unknown): void;
|
|
19
|
+
/** Check custom item type metadata, creation requirements and command option policies before registration. */
|
|
20
|
+
declare function validateItemTypeDefinitions(types: unknown): void;
|
|
21
|
+
/** Validate optional migration metadata and ensure a supplied migration runner is callable. */
|
|
22
|
+
declare function validateMigrationDefinition(definition: unknown): void;
|
|
23
|
+
/** Reject malformed profile dimensions and entries before downstream planners dereference their schema properties. */
|
|
24
|
+
declare function validateProjectProfileDefinition(profile: unknown): void;
|
|
25
|
+
/**
|
|
26
|
+
* Fills an already-validated profile snapshot's optional surfaces — an absent
|
|
27
|
+
* `summary` becomes an empty string and every omitted dimension an empty array —
|
|
28
|
+
* so the stored definition always has the full {@link ProjectProfileDefinition}
|
|
29
|
+
* shape the profile planner and `pm profile` resolution rely on. It runs after
|
|
30
|
+
* validation on the cloned snapshot, so it only ever supplies missing defaults
|
|
31
|
+
* and never has to coerce an invalid type (those are already rejected).
|
|
32
|
+
*/
|
|
33
|
+
declare function applyProjectProfileDefaults(profile: Record<string, unknown>): ProjectProfileDefinition;
|
|
34
|
+
export { applyProjectProfileDefaults, assertFlagValueTypeAndDefault, normalizeCommandDefinitionArguments, normalizeFlagDefinitions, resolveCommandDefinitionAction, validateFlagDefinitions, validateItemFieldDefinitions, validateItemTypeDefinitions, validateMigrationDefinition, validateProjectProfileDefinition };
|