@unbrained/pm-cli 2026.8.12 → 2026.8.14
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 +162 -111
- package/dist/cli/error-guidance.js +4 -8
- package/dist/cli/main.js +40 -3
- package/dist/cli/register-assurance.js +28 -17
- package/dist/cli-bundle/bundle-manifest.json +141 -173
- package/dist/cli-bundle/chunks/chunk-BBOFSVAK.js +197 -0
- package/dist/cli-bundle/chunks/chunk-BFALV3YP.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-WLAHPSOX.js → chunk-FIW4P64F.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BM5YJ2UW.js → chunk-G5JUB66K.js} +52 -52
- package/dist/cli-bundle/chunks/chunk-SBRKH6OR.js +2 -0
- package/dist/cli-bundle/chunks/chunk-TMJ7URWS.js +13 -0
- package/dist/cli-bundle/chunks/chunk-TXMEUUUY.js +8 -0
- package/dist/cli-bundle/chunks/{chunk-KOQMGCTA.js → chunk-XAVMOK6B.js} +50 -50
- package/dist/cli-bundle/chunks/chunk-YAMTJL6Y.js +34 -0
- package/dist/cli-bundle/chunks/chunk-YSVSMJ2B.js +2 -0
- package/dist/cli-bundle/chunks/{register-list-query-XPCJRUUD.js → register-list-query-T3EHHNNV.js} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-4RJCBKRS.js → register-mutation-E27WCLSZ.js} +2 -2
- package/dist/cli-bundle/chunks/register-operations-4R6I7CPY.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-LLHAKP2V.js → register-setup-3YXZ444E.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-JAFRIWVF.js → chunk-4DQ2YERC.js} +4 -4
- package/dist/cli-bundle/focused-chunks/chunk-F43TT2QQ.js +8 -0
- package/dist/cli-bundle/focused-chunks/chunk-K7RWWOAG.js +4 -0
- package/dist/cli-bundle/focused-chunks/chunk-KFSZ3BP6.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-KHM2CS2C.js → chunk-KSEDUWVZ.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-KYUQGTSB.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-ZMGWAYH7.js → chunk-LZ4MV3RH.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-PGXJQLCT.js +155 -0
- package/dist/cli-bundle/focused-chunks/{chunk-RWPAWUOT.js → chunk-PPFGQDSI.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-Q4YY3XNF.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-QK753U3U.js +46 -0
- package/dist/cli-bundle/focused-chunks/chunk-QUMB2J27.js +2 -0
- package/dist/cli-bundle/focused-chunks/chunk-SM7MTG27.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-GQW4BPUT.js → chunk-WCVE2NIG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-XDNAW5OI.js +18 -0
- package/dist/cli-bundle/focused-chunks/{chunk-YIAXMC3T.js → chunk-YOOI3UZX.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-ZM6TZVHC.js +2 -0
- package/dist/cli-bundle/main.js +13 -13
- 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 +45 -41
- 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 +109 -1
- 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 +2 -2
- package/dist/core/checkpoint/checkpoint-gc.js +7 -12
- package/dist/core/extensions/activation-summary-markdown.js +5 -4
- package/dist/core/extensions/activation-summary.d.ts +2 -0
- package/dist/core/extensions/activation-summary.js +6 -2
- package/dist/core/extensions/capability-usage.d.ts +1 -1
- package/dist/core/extensions/capability-usage.js +4 -3
- package/dist/core/extensions/contribution-inventory.d.ts +1 -0
- package/dist/core/extensions/contribution-inventory.js +6 -2
- package/dist/core/extensions/extension-registries.js +3 -2
- package/dist/core/extensions/extension-types.d.ts +83 -1
- package/dist/core/extensions/extension-types.js +3 -2
- package/dist/core/extensions/loader.d.ts +2 -8
- package/dist/core/extensions/loader.js +53 -144
- package/dist/core/extensions/registration-values.d.ts +43 -0
- package/dist/core/extensions/registration-values.js +210 -0
- package/dist/core/extensions/runtime-registrations.d.ts +3 -1
- package/dist/core/extensions/runtime-registrations.js +12 -2
- package/dist/core/fs/fs-utils.d.ts +2 -0
- package/dist/core/fs/fs-utils.js +7 -3
- package/dist/core/history/drift-cache.js +4 -3
- package/dist/core/history/drift-scan.d.ts +6 -0
- package/dist/core/history/drift-scan.js +76 -58
- package/dist/core/history/workspace-history.d.ts +59 -0
- package/dist/core/history/workspace-history.js +197 -10
- package/dist/core/lock/lock-gc.js +8 -13
- package/dist/core/lock/lock.js +5 -4
- package/dist/core/output/output.js +12 -4
- package/dist/core/search/vector-stores.js +6 -11
- package/dist/core/store/item-metadata-cache.js +4 -4
- package/dist/core/telemetry/runtime.d.ts +6 -0
- package/dist/core/telemetry/runtime.js +101 -30
- package/dist/sdk/agent/command-recovery.d.ts +2 -0
- package/dist/sdk/agent/command-recovery.js +10 -2
- package/dist/sdk/annotations.js +4 -4
- package/dist/sdk/cli-contracts/completeness.js +9 -3
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.js +6 -3
- package/dist/sdk/cli-contracts/runtime-contracts.d.ts +6 -1
- package/dist/sdk/cli-contracts/runtime-contracts.js +155 -60
- package/dist/sdk/cli-contracts/schemas/assurance-definition.d.ts +32 -0
- package/dist/sdk/cli-contracts/schemas/assurance-definition.js +25 -2
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +35 -5
- package/dist/sdk/cli-contracts/tool-schema.js +17 -2
- package/dist/sdk/cli-program.js +3 -3
- package/dist/sdk/comments.js +4 -3
- package/dist/sdk/compile-cache.js +4 -3
- package/dist/sdk/compose.d.ts +3 -1
- package/dist/sdk/compose.js +16 -2
- package/dist/sdk/context-relevance.js +12 -4
- package/dist/sdk/context-signal-store.js +4 -3
- package/dist/sdk/extension/install-runtime.js +4 -4
- package/dist/sdk/extension/managed-state.js +4 -3
- package/dist/sdk/extension-contracts.d.ts +1 -1
- package/dist/sdk/flag-invocation-contracts.js +5 -6
- package/dist/sdk/generated/generated-error-code-catalog-part-1.js +14 -2
- package/dist/sdk/governance/assurance-action.d.ts +27 -3
- package/dist/sdk/governance/assurance-action.js +112 -28
- package/dist/sdk/governance/assurance-mutation-error.d.ts +7 -0
- package/dist/sdk/governance/assurance-mutation-error.js +25 -2
- package/dist/sdk/governance/assurance-presets.d.ts +54 -0
- package/dist/sdk/governance/assurance-presets.js +136 -0
- package/dist/sdk/governance/assurance-runtime.d.ts +4 -0
- package/dist/sdk/governance/assurance-runtime.js +109 -8
- package/dist/sdk/governance/assurance.d.ts +39 -0
- package/dist/sdk/governance/assurance.js +145 -6
- package/dist/sdk/governance/gc.js +5 -11
- package/dist/sdk/governance/health.js +18 -6
- package/dist/sdk/governance/validate-history-drift.d.ts +7 -0
- package/dist/sdk/governance/validate-history-drift.js +68 -0
- package/dist/sdk/governance/validate.js +6 -48
- package/dist/sdk/graph/assembly.d.ts +23 -0
- package/dist/sdk/graph/assembly.js +54 -2
- package/dist/sdk/graph/durable-cache.js +91 -3
- package/dist/sdk/graph/governance-contracts.d.ts +12 -0
- package/dist/sdk/graph/governance-contracts.js +29 -0
- package/dist/sdk/graph/governance.d.ts +51 -3
- package/dist/sdk/graph/governance.js +216 -35
- package/dist/sdk/graph/index.d.ts +2 -2
- package/dist/sdk/graph/index.js +4 -4
- package/dist/sdk/graph/mutation-advisory.js +15 -7
- package/dist/sdk/graph/remediation.js +12 -2
- package/dist/sdk/guide.js +4 -4
- package/dist/sdk/history-read.d.ts +8 -0
- package/dist/sdk/history-read.js +2 -2
- package/dist/sdk/index.d.ts +3 -2
- package/dist/sdk/index.js +5 -4
- package/dist/sdk/linked-artifacts.d.ts +2 -0
- package/dist/sdk/linked-artifacts.js +29 -4
- package/dist/sdk/merge/install.js +5 -4
- package/dist/sdk/query/activity.js +4 -3
- package/dist/sdk/query/history.js +20 -3
- package/dist/sdk/read-output-budget.d.ts +2 -0
- package/dist/sdk/read-output-budget.js +12 -5
- package/dist/sdk/read-output-contracts.d.ts +61 -5
- package/dist/sdk/read-output-contracts.js +210 -28
- package/dist/sdk/read-output-rows.d.ts +11 -0
- package/dist/sdk/read-output-rows.js +47 -2
- package/dist/sdk/relationship-history.js +5 -5
- package/dist/sdk/runtime-primitives.d.ts +1 -1
- package/dist/sdk/runtime-primitives.js +3 -3
- package/dist/sdk/runtime.js +5 -3
- package/dist/sdk/schema-migration.js +4 -4
- package/dist/sdk/test/execution.js +4 -4
- package/dist/sdk/workspace-memory.js +4 -4
- package/dist/sdk/workspace-snapshot.js +8 -14
- package/dist/sdk/workspace-transaction-gc.js +4 -9
- package/dist/sdk/workspace-transaction.js +4 -4
- package/dist/sdk/workspace.js +4 -3
- package/docs/ASSURANCE.md +163 -3
- package/docs/COMMANDS.md +31 -2
- package/docs/CONFIGURATION.md +2 -0
- package/docs/EXTENSIONS.md +11 -12
- package/docs/READ_OUTPUT_CONTRACTS.md +44 -8
- package/docs/RELATIONSHIP_GRAPH.md +34 -4
- package/docs/SDK.md +29 -8
- package/docs/SDK_CONTEXT_INTEGRITY.md +32 -1
- package/docs/TESTING.md +47 -16
- package/docs/performance/sdk-entrypoint-import-costs.md +20 -13
- package/marketplace.json +2 -2
- package/package.json +6 -6
- package/packages/pm-beads/extensions/beads/index.ts +1 -0
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/extensions/calendar/index.ts +1 -0
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/extensions/digital-twin/index.ts +7 -0
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/extensions/governance-audit/index.ts +4 -0
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/extensions/guide-shell/index.ts +5 -0
- 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/extensions/linked-test-adapters/index.ts +6 -0
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/extensions/search-advanced/index.ts +2 -0
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/extensions/templates/index.ts +4 -0
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/extensions/todos/index.ts +2 -0
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/extensions/vcs/index.ts +7 -0
- 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/scripts/bundle-cli.mjs +17 -4
- package/sdk/public-surface.json +390 -60
- package/dist/cli-bundle/chunks/chunk-3PS7X6GS.js +0 -8
- package/dist/cli-bundle/chunks/chunk-7KL6KMWF.js +0 -13
- package/dist/cli-bundle/chunks/chunk-D55A5AEN.js +0 -33
- package/dist/cli-bundle/chunks/chunk-KIKDWECH.js +0 -196
- package/dist/cli-bundle/chunks/chunk-R76342NV.js +0 -2
- package/dist/cli-bundle/chunks/chunk-RBTK5EZV.js +0 -5
- package/dist/cli-bundle/chunks/chunk-VLUQOIDT.js +0 -2
- package/dist/cli-bundle/chunks/register-operations-2OGISOVR.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-2DALMVF7.js +0 -5
- package/dist/cli-bundle/focused-chunks/chunk-5OQIMELN.js +0 -155
- package/dist/cli-bundle/focused-chunks/chunk-5TAGTDRE.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-ECADZMVC.js +0 -18
- package/dist/cli-bundle/focused-chunks/chunk-EJGXRA6B.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-FFGSZCPK.js +0 -16
- package/dist/cli-bundle/focused-chunks/chunk-ISKOBJCM.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-KPSXVBDV.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-KTLOKKCQ.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-LGYK3NUF.js +0 -8
- package/dist/cli-bundle/focused-chunks/chunk-NBLUKITQ.js +0 -4
- package/dist/cli-bundle/focused-chunks/chunk-NYLOUPOB.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-Q4T463SD.js +0 -31
- package/dist/cli-bundle/focused-chunks/chunk-QVZVY53N.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-UTEWXDEQ.js +0 -17
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Implements extension runtime contracts and governance for Loader.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!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]="
|
|
7
|
+
!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]="2b8750c3-7b19-5240-8179-f83830af1b77")}catch(e){}}();
|
|
8
8
|
import fs from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { pathToFileURL } from "node:url";
|
|
@@ -23,15 +23,12 @@ import { asRegistrationRecord, assertOptionalBooleanField, assertOptionalFlagDef
|
|
|
23
23
|
import { describeExtensionLongFlagFailure, findExtensionFlagTokenFailure, } from "./flag-definition-validation.js";
|
|
24
24
|
import { compareComparableVersions, evaluatePmMaxVersionBound, evaluatePmMinVersionBound, parseComparableVersion, } from "./version-compat.js";
|
|
25
25
|
import { createRelationshipKindRegistry, } from "../../sdk/relationships.js";
|
|
26
|
-
// Cohesive helper groups now live in sibling modules. They are imported for the
|
|
27
|
-
// discovery/activation code that stays here and re-exported below so existing
|
|
28
|
-
// import sites (sdk/index.ts, commands/extension.ts, health.ts, tests, …) keep
|
|
29
|
-
// importing everything from "./loader.js" unchanged.
|
|
30
26
|
import { normalizeNames, isKnownExtensionCapability, collectUnknownExtensionCapabilities, normalizeManifestCapabilities, formatUnknownExtensionCapabilityWarning, formatLegacyExtensionCapabilityAliasWarning, } from "./extension-capability-aliases.js";
|
|
31
27
|
import { normalizeExtensionPolicy, serializeExtensionPolicy, hydrateExtensionPolicy, normalizePolicySandboxProfile, evaluateExtensionPolicyForExtension, evaluateExtensionPolicyForCapability, evaluateExtensionPolicyForRegistration, } from "./extension-policy.js";
|
|
32
28
|
import { createEmptyExtensionHookRegistry, createEmptyExtensionCommandRegistry, createEmptyExtensionParserRegistry, createEmptyExtensionPreflightRegistry, createEmptyExtensionServiceRegistry, createEmptyExtensionRendererRegistry, createEmptyExtensionRegistrationRegistry, } from "./extension-registries.js";
|
|
33
29
|
import { normalizeCommandName, cloneContextSnapshot, } from "./extension-runtime-helpers.js";
|
|
34
30
|
import { normalizeExtensionContributionInventory } from "./contribution-inventory.js";
|
|
31
|
+
import { attachRuntimeDefinition, assertHookHandler, assertNonEmptyRegistrationString, assertRegistrationFunction, cloneRuntimeRegistrationValue, createRegistrationValidationError, extractRegistrationValidationTrace, isExtensionServiceName, isOutputRendererFormat, normalizeRegistrationRecord, normalizeRegistrationRecordList, normalizeRuntimeRegistrationRecord, normalizeRegistrationName, sanitizeRegistrationValue, toRegistrationCommandPath, validateAssuranceMeasurementProviderDefinition, } from "./registration-values.js";
|
|
35
32
|
import { buildReadyExtensionCandidate, } from "./extension-candidate.js";
|
|
36
33
|
export { parseUnknownExtensionCapabilityWarning, parseLegacyExtensionCapabilityAliasWarning, } from "./extension-capability-aliases.js";
|
|
37
34
|
export { createEmptyExtensionHookRegistry, createEmptyExtensionCommandRegistry, createEmptyExtensionParserRegistry, createEmptyExtensionPreflightRegistry, createEmptyExtensionServiceRegistry, createEmptyExtensionRendererRegistry, createEmptyExtensionRegistrationRegistry, } from "./extension-registries.js";
|
|
@@ -41,7 +38,6 @@ export * from "./extension-types.js";
|
|
|
41
38
|
/** Fallback extension priority used when callers do not provide an override. */
|
|
42
39
|
export const DEFAULT_EXTENSION_PRIORITY = 100;
|
|
43
40
|
let currentPmCliVersionPromise = null;
|
|
44
|
-
/* Types now in extension-types.ts - re-exported via `export * from "./extension-types.js"` above */
|
|
45
41
|
const DEFAULT_EXTENSION_POLICY = Object.freeze(createDefaultExtensionGovernancePolicy());
|
|
46
42
|
let extensionReloadEpoch = 0;
|
|
47
43
|
/** Implements next extension reload token for the public runtime surface of this module. */
|
|
@@ -945,115 +941,6 @@ async function runExtensionDeactivateWithTimeout(deactivate, timeoutMs) {
|
|
|
945
941
|
clearTimeout(timeoutHandle);
|
|
946
942
|
}
|
|
947
943
|
}
|
|
948
|
-
function isOutputRendererFormat(value) {
|
|
949
|
-
return value === "toon" || value === "json";
|
|
950
|
-
}
|
|
951
|
-
function isExtensionServiceName(value) {
|
|
952
|
-
return KNOWN_EXTENSION_SERVICE_NAMES.includes(value);
|
|
953
|
-
}
|
|
954
|
-
function assertHookHandler(hookName, hook) {
|
|
955
|
-
if (typeof hook !== "function") {
|
|
956
|
-
throw new TypeError(`api.hooks.${hookName} requires a function handler`);
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
function assertNonEmptyString(name, value) {
|
|
960
|
-
if (typeof value !== "string" || value.trim().length === 0) {
|
|
961
|
-
throw new TypeError(`${name} requires a non-empty string`);
|
|
962
|
-
}
|
|
963
|
-
return value.trim();
|
|
964
|
-
}
|
|
965
|
-
function assertFunctionHandler(name, value) {
|
|
966
|
-
if (typeof value !== "function") {
|
|
967
|
-
throw new TypeError(`${name} requires a function handler`);
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
function normalizeRegistrationName(name) {
|
|
971
|
-
return name
|
|
972
|
-
.trim()
|
|
973
|
-
.toLowerCase()
|
|
974
|
-
.split(/\s+/)
|
|
975
|
-
.filter((part) => part.length > 0)
|
|
976
|
-
.join(" ");
|
|
977
|
-
}
|
|
978
|
-
function toRegistrationCommandPath(name, action) {
|
|
979
|
-
return normalizeCommandName(`${name} ${action}`);
|
|
980
|
-
}
|
|
981
|
-
function sanitizeRegistrationValue(value) {
|
|
982
|
-
if (value === null) {
|
|
983
|
-
return null;
|
|
984
|
-
}
|
|
985
|
-
if (Array.isArray(value)) {
|
|
986
|
-
return value.map((entry) => sanitizeRegistrationValue(entry));
|
|
987
|
-
}
|
|
988
|
-
if (typeof value === "function") {
|
|
989
|
-
return "[Function]";
|
|
990
|
-
}
|
|
991
|
-
if (typeof value === "bigint") {
|
|
992
|
-
return value.toString();
|
|
993
|
-
}
|
|
994
|
-
if (typeof value === "symbol") {
|
|
995
|
-
return value.toString();
|
|
996
|
-
}
|
|
997
|
-
if (typeof value === "object") {
|
|
998
|
-
const record = value;
|
|
999
|
-
const normalized = {};
|
|
1000
|
-
const keys = Object.keys(record).sort((left, right) => left.localeCompare(right));
|
|
1001
|
-
for (const key of keys) {
|
|
1002
|
-
normalized[key] = sanitizeRegistrationValue(record[key]);
|
|
1003
|
-
}
|
|
1004
|
-
return normalized;
|
|
1005
|
-
}
|
|
1006
|
-
return value;
|
|
1007
|
-
}
|
|
1008
|
-
function cloneRuntimeRegistrationValue(value) {
|
|
1009
|
-
if (Array.isArray(value)) {
|
|
1010
|
-
return value.map((entry) => cloneRuntimeRegistrationValue(entry));
|
|
1011
|
-
}
|
|
1012
|
-
if (typeof value === "object" && value !== null) {
|
|
1013
|
-
const record = value;
|
|
1014
|
-
const cloned = {};
|
|
1015
|
-
for (const key of Object.keys(record).sort((left, right) => left.localeCompare(right))) {
|
|
1016
|
-
cloned[key] = cloneRuntimeRegistrationValue(record[key]);
|
|
1017
|
-
}
|
|
1018
|
-
return cloned;
|
|
1019
|
-
}
|
|
1020
|
-
return value;
|
|
1021
|
-
}
|
|
1022
|
-
const EXTENSION_REGISTRATION_TRACE_SYMBOL = Symbol("extension_registration_trace");
|
|
1023
|
-
function createRegistrationValidationError(message, trace) {
|
|
1024
|
-
const error = new TypeError(message);
|
|
1025
|
-
Object.defineProperty(error, EXTENSION_REGISTRATION_TRACE_SYMBOL, {
|
|
1026
|
-
value: trace,
|
|
1027
|
-
enumerable: false,
|
|
1028
|
-
configurable: false,
|
|
1029
|
-
writable: false,
|
|
1030
|
-
});
|
|
1031
|
-
return error;
|
|
1032
|
-
}
|
|
1033
|
-
function extractRegistrationValidationTrace(error) {
|
|
1034
|
-
if (!(error instanceof Error)) {
|
|
1035
|
-
return undefined;
|
|
1036
|
-
}
|
|
1037
|
-
return error[EXTENSION_REGISTRATION_TRACE_SYMBOL];
|
|
1038
|
-
}
|
|
1039
|
-
function normalizeRegistrationRecord(name, value) {
|
|
1040
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1041
|
-
throw new TypeError(`${name} requires an object definition`);
|
|
1042
|
-
}
|
|
1043
|
-
return sanitizeRegistrationValue(value);
|
|
1044
|
-
}
|
|
1045
|
-
function normalizeRuntimeRegistrationRecord(name, value) {
|
|
1046
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1047
|
-
throw new TypeError(`${name} requires an object definition`);
|
|
1048
|
-
}
|
|
1049
|
-
return cloneRuntimeRegistrationValue(value);
|
|
1050
|
-
}
|
|
1051
|
-
function normalizeRegistrationRecordList(name, value) {
|
|
1052
|
-
if (!Array.isArray(value)) {
|
|
1053
|
-
throw new TypeError(`${name} requires an array of object definitions`);
|
|
1054
|
-
}
|
|
1055
|
-
return value.map((entry) => normalizeRegistrationRecord(name, entry));
|
|
1056
|
-
}
|
|
1057
944
|
const FLAG_DEFINITION_KEYS = new Set([
|
|
1058
945
|
"default",
|
|
1059
946
|
"description",
|
|
@@ -1108,7 +995,7 @@ function normalizeCommandDefinitionArguments(value) {
|
|
|
1108
995
|
const normalized = [];
|
|
1109
996
|
for (const [index, entry] of value.entries()) {
|
|
1110
997
|
const record = asRegistrationRecord(`registerCommand definition.arguments[${index}]`, entry);
|
|
1111
|
-
const name =
|
|
998
|
+
const name = assertNonEmptyRegistrationString(`registerCommand definition.arguments[${index}].name`, record.name);
|
|
1112
999
|
assertOptionalBooleanField(`registerCommand definition.arguments[${index}].required`, record.required);
|
|
1113
1000
|
assertOptionalBooleanField(`registerCommand definition.arguments[${index}].variadic`, record.variadic);
|
|
1114
1001
|
assertOptionalStringField(`registerCommand definition.arguments[${index}].description`, record.description);
|
|
@@ -1218,8 +1105,8 @@ function validateItemFieldDefinitions(fields) {
|
|
|
1218
1105
|
}
|
|
1219
1106
|
for (const [index, raw] of fields.entries()) {
|
|
1220
1107
|
const record = asRegistrationRecord(`registerItemFields fields[${index}]`, raw);
|
|
1221
|
-
|
|
1222
|
-
const fieldType =
|
|
1108
|
+
assertNonEmptyRegistrationString(`registerItemFields fields[${index}].name`, record.name);
|
|
1109
|
+
const fieldType = assertNonEmptyRegistrationString(`registerItemFields fields[${index}].type`, record.type);
|
|
1223
1110
|
if (normalizeItemFieldType(fieldType) === null) {
|
|
1224
1111
|
const suggestion = suggestKnownItemFieldType(fieldType);
|
|
1225
1112
|
const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
|
|
@@ -1241,8 +1128,8 @@ function validateItemTypeCommandOptionPolicies(typeIndex, value) {
|
|
|
1241
1128
|
for (const [policyIndex, rawPolicy] of value.entries()) {
|
|
1242
1129
|
const at = `${label}[${policyIndex}]`;
|
|
1243
1130
|
const policy = asRegistrationRecord(at, rawPolicy);
|
|
1244
|
-
|
|
1245
|
-
|
|
1131
|
+
assertNonEmptyRegistrationString(`${at}.command`, policy.command);
|
|
1132
|
+
assertNonEmptyRegistrationString(`${at}.option`, policy.option);
|
|
1246
1133
|
assertOptionalBooleanField(`${at}.enabled`, policy.enabled);
|
|
1247
1134
|
assertOptionalBooleanField(`${at}.required`, policy.required);
|
|
1248
1135
|
assertOptionalBooleanField(`${at}.visible`, policy.visible);
|
|
@@ -1260,7 +1147,7 @@ function validateItemTypeOptions(typeIndex, value) {
|
|
|
1260
1147
|
for (const [optionIndex, rawOption] of value.entries()) {
|
|
1261
1148
|
const at = `${label}[${optionIndex}]`;
|
|
1262
1149
|
const option = asRegistrationRecord(at, rawOption);
|
|
1263
|
-
|
|
1150
|
+
assertNonEmptyRegistrationString(`${at}.key`, option.key);
|
|
1264
1151
|
assertOptionalStringArrayField(`${at}.values`, option.values);
|
|
1265
1152
|
assertOptionalBooleanField(`${at}.required`, option.required);
|
|
1266
1153
|
assertOptionalStringArrayField(`${at}.aliases`, option.aliases);
|
|
@@ -1273,7 +1160,7 @@ function validateItemTypeDefinitions(types) {
|
|
|
1273
1160
|
for (const [typeIndex, raw] of types.entries()) {
|
|
1274
1161
|
const at = `registerItemTypes types[${typeIndex}]`;
|
|
1275
1162
|
const record = asRegistrationRecord(at, raw);
|
|
1276
|
-
|
|
1163
|
+
assertNonEmptyRegistrationString(`${at}.name`, record.name);
|
|
1277
1164
|
assertOptionalStringField(`${at}.folder`, record.folder);
|
|
1278
1165
|
assertOptionalStringArrayField(`${at}.aliases`, record.aliases);
|
|
1279
1166
|
assertOptionalStringArrayField(`${at}.required_create_fields`, record.required_create_fields);
|
|
@@ -1351,8 +1238,8 @@ const PROJECT_PROFILE_ENTRY_VALIDATORS = {
|
|
|
1351
1238
|
};
|
|
1352
1239
|
function validateProjectProfileDefinition(profile) {
|
|
1353
1240
|
const record = asRegistrationRecord("registerProfile profile", profile);
|
|
1354
|
-
|
|
1355
|
-
|
|
1241
|
+
assertNonEmptyRegistrationString("registerProfile profile.name", record.name);
|
|
1242
|
+
assertNonEmptyRegistrationString("registerProfile profile.title", record.title);
|
|
1356
1243
|
if (record.summary !== undefined && typeof record.summary !== "string") {
|
|
1357
1244
|
throw new TypeError("registerProfile profile.summary must be a string when provided");
|
|
1358
1245
|
}
|
|
@@ -1398,15 +1285,6 @@ function applyProjectProfileDefaults(profile) {
|
|
|
1398
1285
|
}
|
|
1399
1286
|
return profile;
|
|
1400
1287
|
}
|
|
1401
|
-
function attachRuntimeDefinition(entry, runtimeDefinition) {
|
|
1402
|
-
Object.defineProperty(entry, "runtime_definition", {
|
|
1403
|
-
value: runtimeDefinition,
|
|
1404
|
-
enumerable: false,
|
|
1405
|
-
writable: false,
|
|
1406
|
-
configurable: false,
|
|
1407
|
-
});
|
|
1408
|
-
return entry;
|
|
1409
|
-
}
|
|
1410
1288
|
function getDeclaredExtensionCapabilities(extension) {
|
|
1411
1289
|
if (!Array.isArray(extension.capabilities)) {
|
|
1412
1290
|
return null;
|
|
@@ -1515,6 +1393,8 @@ class ExtensionApiRegistrar {
|
|
|
1515
1393
|
this.registerSearchProvider = this.registerSearchProvider.bind(this);
|
|
1516
1394
|
this.registerVectorStoreAdapter =
|
|
1517
1395
|
this.registerVectorStoreAdapter.bind(this);
|
|
1396
|
+
this.registerAssuranceMeasurementProvider =
|
|
1397
|
+
this.registerAssuranceMeasurementProvider.bind(this);
|
|
1518
1398
|
this.hooks = {
|
|
1519
1399
|
beforeCommand: (hook) => this.registerBeforeCommand(hook),
|
|
1520
1400
|
beforeMutation: (hook) => this.registerBeforeMutation(hook),
|
|
@@ -1662,8 +1542,8 @@ class ExtensionApiRegistrar {
|
|
|
1662
1542
|
if (!this.allowRegistration("parser.override", "registerParser", "parser")) {
|
|
1663
1543
|
return;
|
|
1664
1544
|
}
|
|
1665
|
-
const normalizedCommand = normalizeCommandName(
|
|
1666
|
-
|
|
1545
|
+
const normalizedCommand = normalizeCommandName(assertNonEmptyRegistrationString("registerParser command", command));
|
|
1546
|
+
assertRegistrationFunction("registerParser override", override);
|
|
1667
1547
|
this.#parserRegistry.overrides.push({
|
|
1668
1548
|
layer: this.#loadedExtension.layer,
|
|
1669
1549
|
name: this.#loadedExtension.name,
|
|
@@ -1692,7 +1572,7 @@ class ExtensionApiRegistrar {
|
|
|
1692
1572
|
if (!this.allowRegistration("services.override", "registerService", "services", { service: normalizedService })) {
|
|
1693
1573
|
return;
|
|
1694
1574
|
}
|
|
1695
|
-
|
|
1575
|
+
assertRegistrationFunction("registerService override", override);
|
|
1696
1576
|
this.#serviceRegistry.overrides.push({
|
|
1697
1577
|
layer: this.#loadedExtension.layer,
|
|
1698
1578
|
name: this.#loadedExtension.name,
|
|
@@ -1740,7 +1620,7 @@ class ExtensionApiRegistrar {
|
|
|
1740
1620
|
if (!this.allowRegistration("schema.flags", "registerFlags", "schema")) {
|
|
1741
1621
|
return;
|
|
1742
1622
|
}
|
|
1743
|
-
const normalizedTargetCommand = normalizeCommandName(
|
|
1623
|
+
const normalizedTargetCommand = normalizeCommandName(assertNonEmptyRegistrationString("registerFlags targetCommand", targetCommand));
|
|
1744
1624
|
validateFlagDefinitions(flags);
|
|
1745
1625
|
const normalizedFlags = normalizeFlagDefinitions("registerFlags flags", flags);
|
|
1746
1626
|
if (normalizedFlags.length === 0) {
|
|
@@ -1909,8 +1789,8 @@ class ExtensionApiRegistrar {
|
|
|
1909
1789
|
if (!this.allowRegistration("importers.importer", "registerImporter", "importers")) {
|
|
1910
1790
|
return;
|
|
1911
1791
|
}
|
|
1912
|
-
const normalizedName = normalizeRegistrationName(
|
|
1913
|
-
|
|
1792
|
+
const normalizedName = normalizeRegistrationName(assertNonEmptyRegistrationString("registerImporter name", name));
|
|
1793
|
+
assertRegistrationFunction("registerImporter importer", importer);
|
|
1914
1794
|
const commandPath = toRegistrationCommandPath(normalizedName, "import");
|
|
1915
1795
|
// Validate and register optional command metadata before mutating the registry
|
|
1916
1796
|
// so an invalid options object leaves no partial importer registration.
|
|
@@ -1944,8 +1824,8 @@ class ExtensionApiRegistrar {
|
|
|
1944
1824
|
if (!this.allowRegistration("importers.exporter", "registerExporter", "importers")) {
|
|
1945
1825
|
return;
|
|
1946
1826
|
}
|
|
1947
|
-
const normalizedName = normalizeRegistrationName(
|
|
1948
|
-
|
|
1827
|
+
const normalizedName = normalizeRegistrationName(assertNonEmptyRegistrationString("registerExporter name", name));
|
|
1828
|
+
assertRegistrationFunction("registerExporter exporter", exporter);
|
|
1949
1829
|
const commandPath = toRegistrationCommandPath(normalizedName, "export");
|
|
1950
1830
|
// Validate and register optional command metadata before mutating the registry
|
|
1951
1831
|
// so an invalid options object leaves no partial exporter registration.
|
|
@@ -1998,6 +1878,24 @@ class ExtensionApiRegistrar {
|
|
|
1998
1878
|
definition: normalizeRegistrationRecord("registerVectorStoreAdapter adapter", adapter),
|
|
1999
1879
|
}, runtimeDefinition));
|
|
2000
1880
|
}
|
|
1881
|
+
registerAssuranceMeasurementProvider(provider) {
|
|
1882
|
+
assertExtensionCapability(this.#loadedExtension, "services", "registerAssuranceMeasurementProvider");
|
|
1883
|
+
if (!this.allowRegistration("services.assuranceprovider", "registerAssuranceMeasurementProvider", "services")) {
|
|
1884
|
+
return;
|
|
1885
|
+
}
|
|
1886
|
+
validateAssuranceMeasurementProviderDefinition(provider);
|
|
1887
|
+
if (provider.network &&
|
|
1888
|
+
this.#loadedExtension.permissions?.network !== true) {
|
|
1889
|
+
throw new TypeError("registerAssuranceMeasurementProvider network provider requires permissions.network=true");
|
|
1890
|
+
}
|
|
1891
|
+
const runtimeDefinition = normalizeRuntimeRegistrationRecord("registerAssuranceMeasurementProvider provider", provider);
|
|
1892
|
+
this.#registrationRegistry.assurance_providers.push(attachRuntimeDefinition({
|
|
1893
|
+
layer: this.#loadedExtension.layer,
|
|
1894
|
+
name: this.#loadedExtension.name,
|
|
1895
|
+
network_permission: this.#loadedExtension.permissions?.network === true,
|
|
1896
|
+
definition: normalizeRegistrationRecord("registerAssuranceMeasurementProvider provider", provider),
|
|
1897
|
+
}, runtimeDefinition));
|
|
1898
|
+
}
|
|
2001
1899
|
registerBeforeCommand(hook) {
|
|
2002
1900
|
assertExtensionCapability(this.#loadedExtension, "hooks", "api.hooks.beforeCommand");
|
|
2003
1901
|
if (!this.allowRegistration("hooks.beforecommand", "api.hooks.beforeCommand", "hooks"))
|
|
@@ -2089,6 +1987,9 @@ function getRegistrationCounts(registrations) {
|
|
|
2089
1987
|
exporters: registrations.exporters.length,
|
|
2090
1988
|
search_providers: registrations.search_providers.length,
|
|
2091
1989
|
vector_store_adapters: registrations.vector_store_adapters.length,
|
|
1990
|
+
...((registrations.assurance_providers?.length ?? 0) > 0
|
|
1991
|
+
? { assurance_providers: registrations.assurance_providers.length }
|
|
1992
|
+
: {}),
|
|
2092
1993
|
};
|
|
2093
1994
|
}
|
|
2094
1995
|
function collectCommandCollisionWarnings(commands) {
|
|
@@ -2144,7 +2045,9 @@ function collectRendererCollisionWarnings(renderers) {
|
|
|
2144
2045
|
}
|
|
2145
2046
|
const winner = bucket[bucket.length - 1];
|
|
2146
2047
|
for (const displaced of bucket.slice(0, -1)) {
|
|
2147
|
-
if (winner.commands?.length &&
|
|
2048
|
+
if (winner.commands?.length &&
|
|
2049
|
+
displaced.commands?.length &&
|
|
2050
|
+
!displaced.commands.some((command) => winner.commands?.includes(command))) {
|
|
2148
2051
|
continue;
|
|
2149
2052
|
}
|
|
2150
2053
|
warnings.push(`extension_renderer_collision:${format}:${winner.layer}:${winner.name}:${displaced.layer}:${displaced.name}`);
|
|
@@ -2217,7 +2120,13 @@ export async function activateExtensions(loadResult) {
|
|
|
2217
2120
|
}
|
|
2218
2121
|
const failedBeforeActivation = failed.length;
|
|
2219
2122
|
const rollbackPartialActivation = captureExtensionActivationRollback({
|
|
2220
|
-
hooks,
|
|
2123
|
+
hooks,
|
|
2124
|
+
commands,
|
|
2125
|
+
parsers,
|
|
2126
|
+
preflight,
|
|
2127
|
+
services,
|
|
2128
|
+
renderers,
|
|
2129
|
+
registrations,
|
|
2221
2130
|
});
|
|
2222
2131
|
try {
|
|
2223
2132
|
await activatable.activate(createExtensionApi(extension, hooks, commands, parsers, preflight, services, renderers, registrations, warnings, failed, policy));
|
|
@@ -2312,4 +2221,4 @@ export const _testOnlyLoader = {
|
|
|
2312
2221
|
},
|
|
2313
2222
|
};
|
|
2314
2223
|
//# sourceMappingURL=loader.js.map
|
|
2315
|
-
//# debugId=
|
|
2224
|
+
//# debugId=2b8750c3-7b19-5240-8179-f83830af1b77
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/extensions/registration-values
|
|
3
|
+
*
|
|
4
|
+
* Preserves executable extension registrations while producing deterministic,
|
|
5
|
+
* serializable public inventory snapshots and validates assurance providers.
|
|
6
|
+
*/
|
|
7
|
+
import { type AssuranceMeasurementProviderDefinition, type ExtensionActivationFailureTrace, type ExtensionServiceName, type OutputRendererFormat } from "./extension-types.js";
|
|
8
|
+
/** Narrow a string to a renderer format accepted by the extension host. */
|
|
9
|
+
export declare function isOutputRendererFormat(value: string): value is OutputRendererFormat;
|
|
10
|
+
/** Narrow a string to a service name accepted by the extension host. */
|
|
11
|
+
export declare function isExtensionServiceName(value: string): value is ExtensionServiceName;
|
|
12
|
+
/** Require a callable lifecycle hook before registry mutation. */
|
|
13
|
+
export declare function assertHookHandler(hookName: string, hook: unknown): void;
|
|
14
|
+
/** Create a validation error carrying a hidden structured activation trace. */
|
|
15
|
+
export declare function createRegistrationValidationError(message: string, trace: ExtensionActivationFailureTrace): TypeError;
|
|
16
|
+
/** Recover a hidden structured activation trace from a validation error. */
|
|
17
|
+
export declare function extractRegistrationValidationTrace(error: unknown): ExtensionActivationFailureTrace | undefined;
|
|
18
|
+
/** Recursively project an arbitrary registration value into serializable data. */
|
|
19
|
+
export declare function sanitizeRegistrationValue(value: unknown): unknown;
|
|
20
|
+
/** Recursively clone registration containers while preserving function identities. */
|
|
21
|
+
export declare function cloneRuntimeRegistrationValue(value: unknown): unknown;
|
|
22
|
+
/** Create a deterministic serializable registration snapshot with functions redacted. */
|
|
23
|
+
export declare function normalizeRegistrationRecord(name: string, value: unknown): Record<string, unknown>;
|
|
24
|
+
/** Clone a registration record without stripping executable function values. */
|
|
25
|
+
export declare function normalizeRuntimeRegistrationRecord(name: string, value: unknown): Record<string, unknown>;
|
|
26
|
+
/** Normalize every object in an array into deterministic serializable snapshots. */
|
|
27
|
+
export declare function normalizeRegistrationRecordList<T extends object>(name: string, value: readonly T[]): T[];
|
|
28
|
+
/** Normalize an untyped array crossing a JavaScript or JSON boundary. */
|
|
29
|
+
export declare function normalizeRegistrationRecordList(name: string, value: unknown): Array<Record<string, unknown>>;
|
|
30
|
+
/** Require a trimmed non-empty string at an extension authoring boundary. */
|
|
31
|
+
export declare function assertNonEmptyRegistrationString(name: string, value: unknown): string;
|
|
32
|
+
/** Require an executable handler at an extension authoring boundary. */
|
|
33
|
+
export declare function assertRegistrationFunction(name: string, value: unknown): void;
|
|
34
|
+
/** Canonicalize a user-facing registration name for stable routing. */
|
|
35
|
+
export declare function normalizeRegistrationName(name: string): string;
|
|
36
|
+
/** Build the canonical command path synthesized for an importer or exporter. */
|
|
37
|
+
export declare function toRegistrationCommandPath(name: string, action: "import" | "export"): string;
|
|
38
|
+
/** Attach an executable definition as hidden immutable runtime-only state. */
|
|
39
|
+
export declare function attachRuntimeDefinition<TEntry extends {
|
|
40
|
+
definition: Record<string, unknown>;
|
|
41
|
+
}>(entry: TEntry, runtimeDefinition: Record<string, unknown>): TEntry;
|
|
42
|
+
/** Validate the closed provider schema before any activation registry mutation. */
|
|
43
|
+
export declare function validateAssuranceMeasurementProviderDefinition(provider: unknown): asserts provider is AssuranceMeasurementProviderDefinition;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/extensions/registration-values
|
|
3
|
+
*
|
|
4
|
+
* Preserves executable extension registrations while producing deterministic,
|
|
5
|
+
* serializable public inventory snapshots and validates assurance providers.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
!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]="7316b9ef-38e1-5ee0-9107-da15ec7804d4")}catch(e){}}();
|
|
9
|
+
import { KNOWN_EXTENSION_SERVICE_NAMES, } from "./extension-types.js";
|
|
10
|
+
import { asRegistrationRecord, assertOptionalBooleanField, assertOptionalStringField, } from "./registration-validation.js";
|
|
11
|
+
import { normalizeCommandName } from "./extension-runtime-helpers.js";
|
|
12
|
+
/** Narrow a string to a renderer format accepted by the extension host. */
|
|
13
|
+
export function isOutputRendererFormat(value) {
|
|
14
|
+
return value === "toon" || value === "json";
|
|
15
|
+
}
|
|
16
|
+
/** Narrow a string to a service name accepted by the extension host. */
|
|
17
|
+
export function isExtensionServiceName(value) {
|
|
18
|
+
return KNOWN_EXTENSION_SERVICE_NAMES.includes(value);
|
|
19
|
+
}
|
|
20
|
+
/** Require a callable lifecycle hook before registry mutation. */
|
|
21
|
+
export function assertHookHandler(hookName, hook) {
|
|
22
|
+
if (typeof hook !== "function") {
|
|
23
|
+
throw new TypeError(`api.hooks.${hookName} requires a function handler`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const EXTENSION_REGISTRATION_TRACE_SYMBOL = Symbol("extension_registration_trace");
|
|
27
|
+
/** Create a validation error carrying a hidden structured activation trace. */
|
|
28
|
+
export function createRegistrationValidationError(message, trace) {
|
|
29
|
+
const error = new TypeError(message);
|
|
30
|
+
Object.defineProperty(error, EXTENSION_REGISTRATION_TRACE_SYMBOL, {
|
|
31
|
+
value: trace,
|
|
32
|
+
enumerable: false,
|
|
33
|
+
configurable: false,
|
|
34
|
+
writable: false,
|
|
35
|
+
});
|
|
36
|
+
return error;
|
|
37
|
+
}
|
|
38
|
+
/** Recover a hidden structured activation trace from a validation error. */
|
|
39
|
+
export function extractRegistrationValidationTrace(error) {
|
|
40
|
+
return error instanceof Error
|
|
41
|
+
? error[EXTENSION_REGISTRATION_TRACE_SYMBOL]
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
44
|
+
/** Recursively project an arbitrary registration value into serializable data. */
|
|
45
|
+
export function sanitizeRegistrationValue(value) {
|
|
46
|
+
if (value === null)
|
|
47
|
+
return null;
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
return value.map((entry) => sanitizeRegistrationValue(entry));
|
|
50
|
+
}
|
|
51
|
+
if (typeof value === "function")
|
|
52
|
+
return "[Function]";
|
|
53
|
+
if (typeof value === "bigint" || typeof value === "symbol") {
|
|
54
|
+
return value.toString();
|
|
55
|
+
}
|
|
56
|
+
if (typeof value === "object") {
|
|
57
|
+
const record = value;
|
|
58
|
+
const normalized = {};
|
|
59
|
+
for (const key of Object.keys(record).sort((left, right) => left.localeCompare(right))) {
|
|
60
|
+
normalized[key] = sanitizeRegistrationValue(record[key]);
|
|
61
|
+
}
|
|
62
|
+
return normalized;
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
/** Recursively clone registration containers while preserving function identities. */
|
|
67
|
+
export function cloneRuntimeRegistrationValue(value) {
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
return value.map((entry) => cloneRuntimeRegistrationValue(entry));
|
|
70
|
+
}
|
|
71
|
+
if (typeof value === "object" && value !== null) {
|
|
72
|
+
const record = value;
|
|
73
|
+
const cloned = {};
|
|
74
|
+
for (const key of Object.keys(record).sort((left, right) => left.localeCompare(right))) {
|
|
75
|
+
cloned[key] = cloneRuntimeRegistrationValue(record[key]);
|
|
76
|
+
}
|
|
77
|
+
return cloned;
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
/** Create a deterministic serializable registration snapshot with functions redacted. */
|
|
82
|
+
export function normalizeRegistrationRecord(name, value) {
|
|
83
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
84
|
+
throw new TypeError(`${name} requires an object definition`);
|
|
85
|
+
}
|
|
86
|
+
return sanitizeRegistrationValue(value);
|
|
87
|
+
}
|
|
88
|
+
/** Clone a registration record without stripping executable function values. */
|
|
89
|
+
export function normalizeRuntimeRegistrationRecord(name, value) {
|
|
90
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
91
|
+
throw new TypeError(`${name} requires an object definition`);
|
|
92
|
+
}
|
|
93
|
+
return cloneRuntimeRegistrationValue(value);
|
|
94
|
+
}
|
|
95
|
+
/** Implement the typed and untyped registration-array normalization overloads. */
|
|
96
|
+
export function normalizeRegistrationRecordList(name, value) {
|
|
97
|
+
if (!Array.isArray(value)) {
|
|
98
|
+
throw new TypeError(`${name} requires an array of object definitions`);
|
|
99
|
+
}
|
|
100
|
+
return value.map((entry) => normalizeRegistrationRecord(name, entry));
|
|
101
|
+
}
|
|
102
|
+
/** Require a trimmed non-empty string at an extension authoring boundary. */
|
|
103
|
+
export function assertNonEmptyRegistrationString(name, value) {
|
|
104
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
105
|
+
throw new TypeError(`${name} requires a non-empty string`);
|
|
106
|
+
}
|
|
107
|
+
return value.trim();
|
|
108
|
+
}
|
|
109
|
+
/** Require an executable handler at an extension authoring boundary. */
|
|
110
|
+
export function assertRegistrationFunction(name, value) {
|
|
111
|
+
if (typeof value !== "function") {
|
|
112
|
+
throw new TypeError(`${name} requires a function handler`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Canonicalize a user-facing registration name for stable routing. */
|
|
116
|
+
export function normalizeRegistrationName(name) {
|
|
117
|
+
return name
|
|
118
|
+
.trim()
|
|
119
|
+
.toLowerCase()
|
|
120
|
+
.split(/\s+/)
|
|
121
|
+
.filter((part) => part.length > 0)
|
|
122
|
+
.join(" ");
|
|
123
|
+
}
|
|
124
|
+
/** Build the canonical command path synthesized for an importer or exporter. */
|
|
125
|
+
export function toRegistrationCommandPath(name, action) {
|
|
126
|
+
return normalizeCommandName(`${name} ${action}`);
|
|
127
|
+
}
|
|
128
|
+
/** Attach an executable definition as hidden immutable runtime-only state. */
|
|
129
|
+
export function attachRuntimeDefinition(entry, runtimeDefinition) {
|
|
130
|
+
Object.defineProperty(entry, "runtime_definition", {
|
|
131
|
+
value: runtimeDefinition,
|
|
132
|
+
enumerable: false,
|
|
133
|
+
writable: false,
|
|
134
|
+
configurable: false,
|
|
135
|
+
});
|
|
136
|
+
return entry;
|
|
137
|
+
}
|
|
138
|
+
const ASSURANCE_PROVIDER_COST_CLASSES = new Set(["low", "medium", "high"]);
|
|
139
|
+
const ASSURANCE_PROVIDER_VALUE_TYPES = new Set(["number", "string_set"]);
|
|
140
|
+
const ASSURANCE_PROVIDER_PARAMETER_TYPES = new Set([
|
|
141
|
+
"string",
|
|
142
|
+
"number",
|
|
143
|
+
"boolean",
|
|
144
|
+
]);
|
|
145
|
+
function nonEmptyString(label, value) {
|
|
146
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
147
|
+
throw new TypeError(`${label} requires a non-empty string`);
|
|
148
|
+
}
|
|
149
|
+
return value.trim();
|
|
150
|
+
}
|
|
151
|
+
function validateAssuranceProviderKey(providerId, key, definition) {
|
|
152
|
+
const label = `registerAssuranceMeasurementProvider provider.keys.${key}`;
|
|
153
|
+
const record = asRegistrationRecord(label, definition);
|
|
154
|
+
if (!ASSURANCE_PROVIDER_VALUE_TYPES.has(String(record.value_type))) {
|
|
155
|
+
throw new TypeError(`${label}.value_type must be number or string_set`);
|
|
156
|
+
}
|
|
157
|
+
assertOptionalStringField(`${label}.description`, record.description);
|
|
158
|
+
if (record.parameters === undefined)
|
|
159
|
+
return;
|
|
160
|
+
const parameters = asRegistrationRecord(`${label}.parameters`, record.parameters);
|
|
161
|
+
for (const [parameter, rawDefinition] of Object.entries(parameters)) {
|
|
162
|
+
const parameterLabel = `${label}.parameters.${parameter}`;
|
|
163
|
+
nonEmptyString(`${parameterLabel}.name`, parameter);
|
|
164
|
+
const parameterDefinition = asRegistrationRecord(parameterLabel, rawDefinition);
|
|
165
|
+
if (!ASSURANCE_PROVIDER_PARAMETER_TYPES.has(String(parameterDefinition.type))) {
|
|
166
|
+
throw new TypeError(`${parameterLabel}.type must be string, number, or boolean`);
|
|
167
|
+
}
|
|
168
|
+
assertOptionalBooleanField(`${parameterLabel}.required`, parameterDefinition.required);
|
|
169
|
+
assertOptionalStringField(`${parameterLabel}.description`, parameterDefinition.description);
|
|
170
|
+
}
|
|
171
|
+
if (Object.keys(parameters).length > 50) {
|
|
172
|
+
throw new TypeError(`assurance provider ${providerId} key ${key} exceeds 50 parameters`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/** Validate the closed provider schema before any activation registry mutation. */
|
|
176
|
+
export function validateAssuranceMeasurementProviderDefinition(provider) {
|
|
177
|
+
const record = asRegistrationRecord("registerAssuranceMeasurementProvider provider", provider);
|
|
178
|
+
const id = nonEmptyString("registerAssuranceMeasurementProvider provider.id", record.id);
|
|
179
|
+
if (!/^[a-z0-9][a-z0-9-]*$/u.test(id)) {
|
|
180
|
+
throw new TypeError("registerAssuranceMeasurementProvider provider.id must be a stable lowercase id");
|
|
181
|
+
}
|
|
182
|
+
if (!ASSURANCE_PROVIDER_COST_CLASSES.has(String(record.cost_class))) {
|
|
183
|
+
throw new TypeError("registerAssuranceMeasurementProvider provider.cost_class must be low, medium, or high");
|
|
184
|
+
}
|
|
185
|
+
if (typeof record.network !== "boolean") {
|
|
186
|
+
throw new TypeError("registerAssuranceMeasurementProvider provider.network must be boolean");
|
|
187
|
+
}
|
|
188
|
+
const keys = asRegistrationRecord("registerAssuranceMeasurementProvider provider.keys", record.keys);
|
|
189
|
+
if (Object.keys(keys).length === 0) {
|
|
190
|
+
throw new TypeError("registerAssuranceMeasurementProvider provider.keys requires at least one key");
|
|
191
|
+
}
|
|
192
|
+
for (const [key, definition] of Object.entries(keys)) {
|
|
193
|
+
if (!/^[a-z0-9][a-z0-9-]*$/u.test(key)) {
|
|
194
|
+
throw new TypeError(`registerAssuranceMeasurementProvider provider key ${key} must be a stable lowercase id`);
|
|
195
|
+
}
|
|
196
|
+
validateAssuranceProviderKey(id, key, definition);
|
|
197
|
+
}
|
|
198
|
+
if (record.timeout_ms !== undefined &&
|
|
199
|
+
(typeof record.timeout_ms !== "number" ||
|
|
200
|
+
!Number.isInteger(record.timeout_ms) ||
|
|
201
|
+
record.timeout_ms < 1 ||
|
|
202
|
+
record.timeout_ms > 300_000)) {
|
|
203
|
+
throw new TypeError("registerAssuranceMeasurementProvider provider.timeout_ms must be an integer from 1 through 300000");
|
|
204
|
+
}
|
|
205
|
+
if (typeof record.resolve !== "function") {
|
|
206
|
+
throw new TypeError("registerAssuranceMeasurementProvider provider.resolve requires a function handler");
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=registration-values.js.map
|
|
210
|
+
//# debugId=7316b9ef-38e1-5ee0-9107-da15ec7804d4
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Implements extension runtime contracts and governance for Runtime Registrations.
|
|
5
5
|
*/
|
|
6
|
-
import type { ExtensionRegistrationRegistry, RegisteredExtensionSchemaMigrationDefinition, RegisteredExtensionSearchProvider, RegisteredExtensionVectorStoreAdapter, SchemaFieldDefinition } from "./loader.js";
|
|
6
|
+
import type { ExtensionRegistrationRegistry, RegisteredExtensionSchemaMigrationDefinition, RegisteredExtensionSearchProvider, RegisteredExtensionVectorStoreAdapter, RegisteredExtensionAssuranceMeasurementProvider, SchemaFieldDefinition } from "./loader.js";
|
|
7
|
+
/** Resolve the last-activated assurance provider with the requested stable id. */
|
|
8
|
+
export declare function resolveRegisteredAssuranceMeasurementProvider(registrations: ExtensionRegistrationRegistry | null, providerId: string | undefined): RegisteredExtensionAssuranceMeasurementProvider | null;
|
|
7
9
|
/** Implements collect registered item fields for the public runtime surface of this module. */
|
|
8
10
|
export declare function collectRegisteredItemFields(registrations: ExtensionRegistrationRegistry | null): SchemaFieldDefinition[];
|
|
9
11
|
/** Implements resolve registered search provider for the public runtime surface of this module. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="ab276268-7a98-5f97-b3f5-300dfd1b5ed5")}catch(e){}}();
|
|
3
3
|
function normalizeRegistrationName(value) {
|
|
4
4
|
if (typeof value !== "string") {
|
|
5
5
|
return null;
|
|
@@ -7,6 +7,16 @@ function normalizeRegistrationName(value) {
|
|
|
7
7
|
const normalized = value.trim().toLowerCase();
|
|
8
8
|
return normalized.length > 0 ? normalized : null;
|
|
9
9
|
}
|
|
10
|
+
/** Resolve the last-activated assurance provider with the requested stable id. */
|
|
11
|
+
export function resolveRegisteredAssuranceMeasurementProvider(registrations, providerId) {
|
|
12
|
+
const normalizedId = normalizeRegistrationName(providerId);
|
|
13
|
+
if (!registrations || !normalizedId)
|
|
14
|
+
return null;
|
|
15
|
+
return ([...(registrations.assurance_providers ?? [])]
|
|
16
|
+
.reverse()
|
|
17
|
+
.find((registration) => normalizeRegistrationName(registration.definition.id) ===
|
|
18
|
+
normalizedId) ?? null);
|
|
19
|
+
}
|
|
10
20
|
/** Implements collect registered item fields for the public runtime surface of this module. */
|
|
11
21
|
export function collectRegisteredItemFields(registrations) {
|
|
12
22
|
if (!registrations) {
|
|
@@ -55,4 +65,4 @@ export function getMigrationRuntimeDefinition(migration) {
|
|
|
55
65
|
return migration.runtime_definition ?? migration.definition;
|
|
56
66
|
}
|
|
57
67
|
//# sourceMappingURL=runtime-registrations.js.map
|
|
58
|
-
//# debugId=
|
|
68
|
+
//# debugId=ab276268-7a98-5f97-b3f5-300dfd1b5ed5
|
|
@@ -12,6 +12,8 @@ export declare function pathExists(targetPath: string): Promise<boolean>;
|
|
|
12
12
|
* runtime fault instead of reaching the caller's own root validation.
|
|
13
13
|
*/
|
|
14
14
|
export declare function isFileAbsentError(error: unknown): boolean;
|
|
15
|
+
/** Report an exact missing-entry race while preserving ENOTDIR as structural corruption. */
|
|
16
|
+
export declare function isFileMissingError(error: unknown): boolean;
|
|
15
17
|
/** Implements read file if exists for the public runtime surface of this module. */
|
|
16
18
|
export declare function readFileIfExists(targetPath: string): Promise<string | null>;
|
|
17
19
|
/** Implements write file atomic for the public runtime surface of this module. */
|