@unbrained/pm-cli 2026.5.24 → 2026.5.28
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/CHANGELOG.md +953 -522
- package/README.md +2 -10
- package/dist/cli/bootstrap-args.d.ts +18 -1
- package/dist/cli/bootstrap-args.js +143 -3
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commander-usage.js +134 -11
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/append.js +4 -3
- package/dist/cli/commands/append.js.map +1 -1
- package/dist/cli/commands/claim.js +5 -4
- package/dist/cli/commands/claim.js.map +1 -1
- package/dist/cli/commands/close.d.ts +3 -0
- package/dist/cli/commands/close.js +26 -3
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/completion.d.ts +2 -2
- package/dist/cli/commands/completion.js +109 -56
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/config.d.ts +1 -1
- package/dist/cli/commands/config.js +82 -4
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/create.js +7 -272
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/delete.js +4 -3
- package/dist/cli/commands/delete.js.map +1 -1
- package/dist/cli/commands/docs.d.ts +1 -12
- package/dist/cli/commands/docs.js +8 -312
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/extension/bundled-catalog.d.ts +14 -0
- package/dist/cli/commands/extension/bundled-catalog.js +268 -0
- package/dist/cli/commands/extension/bundled-catalog.js.map +1 -0
- package/dist/cli/commands/extension/doctor.d.ts +31 -0
- package/dist/cli/commands/extension/doctor.js +345 -0
- package/dist/cli/commands/extension/doctor.js.map +1 -0
- package/dist/cli/commands/extension/install-sources.d.ts +37 -0
- package/dist/cli/commands/extension/install-sources.js +384 -0
- package/dist/cli/commands/extension/install-sources.js.map +1 -0
- package/dist/cli/commands/extension/managed-state.d.ts +48 -0
- package/dist/cli/commands/extension/managed-state.js +172 -0
- package/dist/cli/commands/extension/managed-state.js.map +1 -0
- package/dist/cli/commands/extension/scaffold.d.ts +14 -0
- package/dist/cli/commands/extension/scaffold.js +202 -0
- package/dist/cli/commands/extension/scaffold.js.map +1 -0
- package/dist/cli/commands/extension/shared.d.ts +14 -0
- package/dist/cli/commands/extension/shared.js +106 -0
- package/dist/cli/commands/extension/shared.js.map +1 -0
- package/dist/cli/commands/extension.d.ts +36 -68
- package/dist/cli/commands/extension.js +143 -1422
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/files.d.ts +1 -12
- package/dist/cli/commands/files.js +11 -308
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/get.js +4 -3
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/health.js +17 -3
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history-redact.js +23 -18
- package/dist/cli/commands/history-redact.js.map +1 -1
- package/dist/cli/commands/history-repair.js +24 -18
- package/dist/cli/commands/history-repair.js.map +1 -1
- package/dist/cli/commands/legacy-none-tokens.d.ts +3 -0
- package/dist/cli/commands/legacy-none-tokens.js +39 -0
- package/dist/cli/commands/legacy-none-tokens.js.map +1 -0
- package/dist/cli/commands/linked-artifacts.d.ts +96 -0
- package/dist/cli/commands/linked-artifacts.js +335 -0
- package/dist/cli/commands/linked-artifacts.js.map +1 -0
- package/dist/cli/commands/linked-test-parsers.d.ts +28 -0
- package/dist/cli/commands/linked-test-parsers.js +192 -0
- package/dist/cli/commands/linked-test-parsers.js.map +1 -0
- package/dist/cli/commands/list.js +19 -5
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/normalize.js +4 -3
- package/dist/cli/commands/normalize.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +5 -0
- package/dist/cli/commands/plan.js +56 -8
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/recurrence-parsers.d.ts +26 -0
- package/dist/cli/commands/recurrence-parsers.js +98 -0
- package/dist/cli/commands/recurrence-parsers.js.map +1 -0
- package/dist/cli/commands/restore.js +19 -8
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/search.js +5 -8
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/test/linked-command-detection.d.ts +37 -0
- package/dist/cli/commands/test/linked-command-detection.js +200 -0
- package/dist/cli/commands/test/linked-command-detection.js.map +1 -0
- package/dist/cli/commands/test.d.ts +1 -2
- package/dist/cli/commands/test.js +8 -350
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update-many.js +4 -3
- package/dist/cli/commands/update-many.js.map +1 -1
- package/dist/cli/commands/update.js +83 -356
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/validate.js +32 -12
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +1 -0
- package/dist/cli/error-guidance.js +6 -2
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/main.d.ts +11 -0
- package/dist/cli/main.js +76 -28
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.d.ts +4 -1
- package/dist/cli/register-list-query.js +242 -203
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +73 -11
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +3 -3
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +12 -7
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.js +3 -2
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli.js +4 -3
- package/dist/cli.js.map +1 -1
- package/dist/core/config/positional-value.d.ts +44 -0
- package/dist/core/config/positional-value.js +109 -0
- package/dist/core/config/positional-value.js.map +1 -0
- package/dist/core/extensions/extension-capability-aliases.d.ts +14 -0
- package/dist/core/extensions/extension-capability-aliases.js +159 -0
- package/dist/core/extensions/extension-capability-aliases.js.map +1 -0
- package/dist/core/extensions/extension-hook-runtime.d.ts +13 -0
- package/dist/core/extensions/extension-hook-runtime.js +414 -0
- package/dist/core/extensions/extension-hook-runtime.js.map +1 -0
- package/dist/core/extensions/extension-policy.d.ts +69 -0
- package/dist/core/extensions/extension-policy.js +481 -0
- package/dist/core/extensions/extension-policy.js.map +1 -0
- package/dist/core/extensions/extension-registries.d.ts +8 -0
- package/dist/core/extensions/extension-registries.js +52 -0
- package/dist/core/extensions/extension-registries.js.map +1 -0
- package/dist/core/extensions/extension-runtime-helpers.d.ts +6 -0
- package/dist/core/extensions/extension-runtime-helpers.js +29 -0
- package/dist/core/extensions/extension-runtime-helpers.js.map +1 -0
- package/dist/core/extensions/extension-types.d.ts +13 -39
- package/dist/core/extensions/extension-types.js +34 -2
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +7 -0
- package/dist/core/extensions/index.js +11 -2
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +4 -22
- package/dist/core/extensions/loader.js +22 -1139
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/history/drift-scan.d.ts +11 -0
- package/dist/core/history/drift-scan.js +114 -32
- package/dist/core/history/drift-scan.js.map +1 -1
- package/dist/core/history/history-rewrite.d.ts +43 -0
- package/dist/core/history/history-rewrite.js +48 -0
- package/dist/core/history/history-rewrite.js.map +1 -0
- package/dist/core/history/history.js +5 -4
- package/dist/core/history/history.js.map +1 -1
- package/dist/core/history/replay.js +4 -3
- package/dist/core/history/replay.js.map +1 -1
- package/dist/core/item/item-record.d.ts +19 -0
- package/dist/core/item/item-record.js +24 -0
- package/dist/core/item/item-record.js.map +1 -0
- package/dist/core/output/mutation-projection.d.ts +31 -0
- package/dist/core/output/mutation-projection.js +103 -0
- package/dist/core/output/mutation-projection.js.map +1 -0
- package/dist/core/output/output.d.ts +2 -0
- package/dist/core/output/output.js +5 -3
- package/dist/core/output/output.js.map +1 -1
- package/dist/core/schema/runtime-schema.js +8 -38
- package/dist/core/schema/runtime-schema.js.map +1 -1
- package/dist/core/search/vector-stores.js +46 -9
- package/dist/core/search/vector-stores.js.map +1 -1
- package/dist/core/sentry/helpers.d.ts +1 -1
- package/dist/core/sentry/helpers.js +20 -3
- package/dist/core/sentry/helpers.js.map +1 -1
- package/dist/core/shared/command-types.d.ts +1 -0
- package/dist/core/shared/command-types.js +2 -2
- package/dist/core/shared/command-types.js.map +1 -1
- package/dist/core/shared/constants.d.ts +10 -1
- package/dist/core/shared/constants.js +56 -58
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/levenshtein.js +23 -7
- package/dist/core/shared/levenshtein.js.map +1 -1
- package/dist/core/shared/primitives.d.ts +23 -0
- package/dist/core/shared/primitives.js +39 -2
- package/dist/core/shared/primitives.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +16 -2
- package/dist/core/store/front-matter-cache.js +99 -33
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/core/store/item-store.js +8 -73
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/mcp/server.js +76 -28
- package/dist/mcp/server.js.map +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +20 -0
- package/dist/sdk/cli-contracts/enum-contracts.js +156 -0
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +14 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +243 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +11 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +901 -0
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +11 -33
- package/dist/sdk/cli-contracts.js +30 -1356
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/package-import-adapters.d.ts +74 -0
- package/dist/sdk/package-import-adapters.js +186 -0
- package/dist/sdk/package-import-adapters.js.map +1 -0
- package/dist/sdk/package-runtime-options.d.ts +26 -0
- package/dist/sdk/package-runtime-options.js +71 -0
- package/dist/sdk/package-runtime-options.js.map +1 -0
- package/dist/sdk/runtime.d.ts +2 -0
- package/dist/sdk/runtime.js +4 -2
- package/dist/sdk/runtime.js.map +1 -1
- package/docs/AGENT_GUIDE.md +6 -10
- package/docs/CLAUDE_CODE_PLUGIN.md +5 -28
- package/docs/CODEX_PLUGIN.md +5 -5
- package/docs/COMMANDS.md +19 -3
- package/docs/CONFIGURATION.md +15 -0
- package/docs/EXTENSIONS.md +4 -63
- package/docs/RELEASING.md +4 -4
- package/marketplace.json +7 -3
- package/package.json +9 -6
- package/packages/pm-beads/extensions/beads/index.js +2 -49
- package/packages/pm-beads/extensions/beads/index.ts +2 -54
- package/packages/pm-beads/extensions/beads/runtime-loader.js +86 -0
- package/packages/pm-beads/extensions/beads/runtime-loader.ts +88 -0
- package/packages/pm-beads/extensions/beads/runtime.js +26 -115
- package/packages/pm-beads/extensions/beads/runtime.ts +33 -132
- package/packages/pm-calendar/extensions/calendar/index.js +47 -2
- package/packages/pm-calendar/extensions/calendar/index.ts +52 -2
- package/packages/pm-calendar/extensions/calendar/runtime.js +1 -0
- package/packages/pm-calendar/extensions/calendar/runtime.ts +1 -0
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +14 -41
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +25 -41
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +10 -50
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +17 -50
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +8 -40
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +10 -40
- package/packages/pm-search-advanced/extensions/search-advanced/index.js +1 -1
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +4 -37
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +6 -37
- package/packages/pm-todos/extensions/todos/index.js +3 -50
- package/packages/pm-todos/extensions/todos/index.ts +3 -55
- package/packages/pm-todos/extensions/todos/runtime-loader.js +86 -0
- package/packages/pm-todos/extensions/todos/runtime-loader.ts +88 -0
- package/packages/pm-todos/extensions/todos/runtime.js +24 -117
- package/packages/pm-todos/extensions/todos/runtime.ts +32 -129
- package/plugins/pm-claude/README.md +2 -2
- package/plugins/pm-claude/commands/pm-planner.md +1 -15
- package/plugins/pm-claude/scripts/pm-mcp-server.mjs +5 -2
- package/plugins/pm-claude/skills/pm-planner/SKILL.md +3 -21
- package/plugins/pm-codex/scripts/pm-mcp-server.mjs +15 -6
- package/plugins/pm-codex/skills/pm-native/SKILL.md +1 -13
- package/PRD.md +0 -1734
|
@@ -1,680 +1,33 @@
|
|
|
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]="4fba8687-0797-5479-afc8-12f1a2e5a954")}catch(e){}}();
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
6
|
import { pathExists } from "../fs/fs-utils.js";
|
|
7
7
|
import { isPathWithinDirectory } from "../fs/path-utils.js";
|
|
8
8
|
import { resolveGlobalPmRoot } from "../store/paths.js";
|
|
9
|
-
import {
|
|
9
|
+
import { asRecordLoose } from "../shared/primitives.js";
|
|
10
|
+
// Cohesive helper groups now live in sibling modules. They are imported for the
|
|
11
|
+
// discovery/activation code that stays here and re-exported below so existing
|
|
12
|
+
// import sites (sdk/index.ts, commands/extension.ts, health.ts, tests, …) keep
|
|
13
|
+
// importing everything from "./loader.js" unchanged.
|
|
14
|
+
import { normalizeNames, isKnownExtensionCapability, collectUnknownExtensionCapabilities, normalizeManifestCapabilities, formatUnknownExtensionCapabilityWarning, formatLegacyExtensionCapabilityAliasWarning, } from "./extension-capability-aliases.js";
|
|
15
|
+
import { normalizeExtensionPolicy, serializeExtensionPolicy, hydrateExtensionPolicy, normalizePolicySandboxProfile, evaluateExtensionPolicyForExtension, evaluateExtensionPolicyForCapability, evaluateExtensionPolicyForRegistration, } from "./extension-policy.js";
|
|
16
|
+
import { createEmptyExtensionHookRegistry, createEmptyExtensionCommandRegistry, createEmptyExtensionParserRegistry, createEmptyExtensionPreflightRegistry, createEmptyExtensionServiceRegistry, createEmptyExtensionRendererRegistry, createEmptyExtensionRegistrationRegistry, } from "./extension-registries.js";
|
|
17
|
+
import { normalizeCommandName, cloneContextSnapshot, } from "./extension-runtime-helpers.js";
|
|
18
|
+
export { parseUnknownExtensionCapabilityWarning, parseLegacyExtensionCapabilityAliasWarning, } from "./extension-capability-aliases.js";
|
|
19
|
+
export { createEmptyExtensionHookRegistry, createEmptyExtensionCommandRegistry, createEmptyExtensionParserRegistry, createEmptyExtensionPreflightRegistry, createEmptyExtensionServiceRegistry, createEmptyExtensionRendererRegistry, createEmptyExtensionRegistrationRegistry, } from "./extension-registries.js";
|
|
20
|
+
export { runBeforeCommandHooks, runAfterCommandHooks, runOnWriteHooks, runOnReadHooks, runOnIndexHooks, runCommandHandler, runParserOverride, runPreflightOverride, runServiceOverrideSync, runServiceOverride, runCommandOverride, runRendererOverride, } from "./extension-hook-runtime.js";
|
|
21
|
+
import { KNOWN_EXTENSION_SERVICE_NAMES, createDefaultExtensionGovernancePolicy, } from "./extension-types.js";
|
|
10
22
|
export * from "./extension-types.js";
|
|
11
23
|
const DEFAULT_EXTENSION_PRIORITY = 100;
|
|
12
24
|
/* Types now in extension-types.ts - re-exported via `export * from "./extension-types.js"` above */
|
|
13
|
-
|
|
14
|
-
return [...new Set(values.map((value) => value.trim()).filter((value) => value.length > 0))].sort((a, b) => a.localeCompare(b));
|
|
15
|
-
}
|
|
16
|
-
function isKnownExtensionCapability(value) {
|
|
17
|
-
return KNOWN_EXTENSION_CAPABILITIES.includes(value);
|
|
18
|
-
}
|
|
19
|
-
function collectUnknownExtensionCapabilities(capabilities) {
|
|
20
|
-
return capabilities.filter((capability) => !isKnownExtensionCapability(capability));
|
|
21
|
-
}
|
|
22
|
-
const DEFAULT_EXTENSION_POLICY = Object.freeze({
|
|
23
|
-
mode: "off",
|
|
24
|
-
trust_mode: "off",
|
|
25
|
-
require_provenance: false,
|
|
26
|
-
trusted_extensions: [],
|
|
27
|
-
default_sandbox_profile: "none",
|
|
28
|
-
allowed_extensions: [],
|
|
29
|
-
blocked_extensions: [],
|
|
30
|
-
allowed_capabilities: [],
|
|
31
|
-
blocked_capabilities: [],
|
|
32
|
-
allowed_surfaces: [],
|
|
33
|
-
blocked_surfaces: [],
|
|
34
|
-
allowed_commands: [],
|
|
35
|
-
blocked_commands: [],
|
|
36
|
-
allowed_actions: [],
|
|
37
|
-
blocked_actions: [],
|
|
38
|
-
allowed_services: [],
|
|
39
|
-
blocked_services: [],
|
|
40
|
-
extension_overrides: [],
|
|
41
|
-
});
|
|
25
|
+
const DEFAULT_EXTENSION_POLICY = Object.freeze(createDefaultExtensionGovernancePolicy());
|
|
42
26
|
let extensionReloadEpoch = 0;
|
|
43
27
|
export function nextExtensionReloadToken(seed = Date.now()) {
|
|
44
28
|
extensionReloadEpoch += 1;
|
|
45
29
|
return `${extensionReloadEpoch}-${seed}`;
|
|
46
30
|
}
|
|
47
|
-
function normalizePolicyName(value) {
|
|
48
|
-
if (typeof value !== "string") {
|
|
49
|
-
return "";
|
|
50
|
-
}
|
|
51
|
-
return value.trim().toLowerCase();
|
|
52
|
-
}
|
|
53
|
-
function normalizePolicyStringSet(values) {
|
|
54
|
-
return new Set((values ?? [])
|
|
55
|
-
.map((value) => value.trim().toLowerCase())
|
|
56
|
-
.filter((value) => value.length > 0));
|
|
57
|
-
}
|
|
58
|
-
function normalizePolicySurfaceToken(value) {
|
|
59
|
-
const normalized = value.trim().toLowerCase();
|
|
60
|
-
if (normalized.length === 0) {
|
|
61
|
-
return "";
|
|
62
|
-
}
|
|
63
|
-
const segments = normalized
|
|
64
|
-
.split(/[.:/]/)
|
|
65
|
-
.map((segment) => segment.replace(/[\s_-]+/g, ""))
|
|
66
|
-
.filter((segment) => segment.length > 0);
|
|
67
|
-
if (segments.length === 0) {
|
|
68
|
-
return "";
|
|
69
|
-
}
|
|
70
|
-
if (segments.length === 1) {
|
|
71
|
-
return segments[0];
|
|
72
|
-
}
|
|
73
|
-
return `${segments[0]}.${segments.slice(1).join("")}`;
|
|
74
|
-
}
|
|
75
|
-
function normalizePolicySurfaceSet(values) {
|
|
76
|
-
return new Set((values ?? [])
|
|
77
|
-
.map((value) => normalizePolicySurfaceToken(value))
|
|
78
|
-
.filter((value) => value.length > 0));
|
|
79
|
-
}
|
|
80
|
-
function normalizePolicyMode(value) {
|
|
81
|
-
const normalized = normalizePolicyName(value);
|
|
82
|
-
if (KNOWN_EXTENSION_POLICY_MODES.includes(normalized)) {
|
|
83
|
-
return normalized;
|
|
84
|
-
}
|
|
85
|
-
return "off";
|
|
86
|
-
}
|
|
87
|
-
function normalizePolicyTrustMode(value) {
|
|
88
|
-
const normalized = normalizePolicyName(value);
|
|
89
|
-
if (KNOWN_EXTENSION_TRUST_MODES.includes(normalized)) {
|
|
90
|
-
return normalized;
|
|
91
|
-
}
|
|
92
|
-
return "off";
|
|
93
|
-
}
|
|
94
|
-
function normalizePolicySandboxProfile(value) {
|
|
95
|
-
const normalized = normalizePolicyName(value);
|
|
96
|
-
if (KNOWN_EXTENSION_SANDBOX_PROFILES.includes(normalized)) {
|
|
97
|
-
return normalized;
|
|
98
|
-
}
|
|
99
|
-
return "none";
|
|
100
|
-
}
|
|
101
|
-
function toSortedList(values) {
|
|
102
|
-
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
103
|
-
}
|
|
104
|
-
function normalizeExtensionPolicy(settings) {
|
|
105
|
-
const policy = settings.extensions.policy;
|
|
106
|
-
const mode = normalizePolicyMode(policy?.mode);
|
|
107
|
-
const trustMode = normalizePolicyTrustMode(policy?.trust_mode);
|
|
108
|
-
const requireProvenance = policy?.require_provenance === true;
|
|
109
|
-
const trustedExtensions = normalizePolicyStringSet(policy?.trusted_extensions);
|
|
110
|
-
const defaultSandboxProfile = normalizePolicySandboxProfile(policy?.default_sandbox_profile);
|
|
111
|
-
const allowedExtensions = normalizePolicyStringSet(policy?.allowed_extensions);
|
|
112
|
-
const blockedExtensions = normalizePolicyStringSet(policy?.blocked_extensions);
|
|
113
|
-
const allowedCapabilities = normalizePolicyStringSet(policy?.allowed_capabilities);
|
|
114
|
-
const blockedCapabilities = normalizePolicyStringSet(policy?.blocked_capabilities);
|
|
115
|
-
const allowedSurfaces = normalizePolicySurfaceSet(policy?.allowed_surfaces);
|
|
116
|
-
const blockedSurfaces = normalizePolicySurfaceSet(policy?.blocked_surfaces);
|
|
117
|
-
const allowedCommands = normalizePolicyStringSet(policy?.allowed_commands);
|
|
118
|
-
const blockedCommands = normalizePolicyStringSet(policy?.blocked_commands);
|
|
119
|
-
const allowedActions = normalizePolicyStringSet(policy?.allowed_actions);
|
|
120
|
-
const blockedActions = normalizePolicyStringSet(policy?.blocked_actions);
|
|
121
|
-
const allowedServices = normalizePolicyStringSet(policy?.allowed_services);
|
|
122
|
-
const blockedServices = normalizePolicyStringSet(policy?.blocked_services);
|
|
123
|
-
const overridesByName = new Map();
|
|
124
|
-
for (const rawOverride of policy?.extension_overrides ?? []) {
|
|
125
|
-
const name = normalizePolicyName(rawOverride.name);
|
|
126
|
-
if (name.length === 0) {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
overridesByName.set(name, {
|
|
130
|
-
name,
|
|
131
|
-
disabled: rawOverride.disabled === true,
|
|
132
|
-
requireTrusted: rawOverride.require_trusted === true,
|
|
133
|
-
requireProvenance: rawOverride.require_provenance === true,
|
|
134
|
-
sandboxProfile: rawOverride.sandbox_profile !== undefined
|
|
135
|
-
? normalizePolicySandboxProfile(rawOverride.sandbox_profile)
|
|
136
|
-
: undefined,
|
|
137
|
-
allowedCapabilities: normalizePolicyStringSet(rawOverride.allowed_capabilities),
|
|
138
|
-
blockedCapabilities: normalizePolicyStringSet(rawOverride.blocked_capabilities),
|
|
139
|
-
allowedSurfaces: normalizePolicySurfaceSet(rawOverride.allowed_surfaces),
|
|
140
|
-
blockedSurfaces: normalizePolicySurfaceSet(rawOverride.blocked_surfaces),
|
|
141
|
-
allowedCommands: normalizePolicyStringSet(rawOverride.allowed_commands),
|
|
142
|
-
blockedCommands: normalizePolicyStringSet(rawOverride.blocked_commands),
|
|
143
|
-
allowedActions: normalizePolicyStringSet(rawOverride.allowed_actions),
|
|
144
|
-
blockedActions: normalizePolicyStringSet(rawOverride.blocked_actions),
|
|
145
|
-
allowedServices: normalizePolicyStringSet(rawOverride.allowed_services),
|
|
146
|
-
blockedServices: normalizePolicyStringSet(rawOverride.blocked_services),
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
const warnings = [];
|
|
150
|
-
for (const capability of toSortedList([...allowedCapabilities, ...blockedCapabilities])) {
|
|
151
|
-
if (!isKnownExtensionCapability(capability)) {
|
|
152
|
-
warnings.push(`extension_policy_unknown_capability:${capability}`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
for (const override of [...overridesByName.values()].sort((left, right) => left.name.localeCompare(right.name))) {
|
|
156
|
-
for (const capability of toSortedList([...override.allowedCapabilities, ...override.blockedCapabilities])) {
|
|
157
|
-
if (!isKnownExtensionCapability(capability)) {
|
|
158
|
-
warnings.push(`extension_policy_unknown_capability:${override.name}:${capability}`);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
const knownSurfaces = new Set(KNOWN_EXTENSION_POLICY_SURFACES);
|
|
163
|
-
for (const surface of toSortedList([...allowedSurfaces, ...blockedSurfaces])) {
|
|
164
|
-
if (!knownSurfaces.has(surface)) {
|
|
165
|
-
warnings.push(`extension_policy_unknown_surface:${surface}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
for (const override of [...overridesByName.values()].sort((left, right) => left.name.localeCompare(right.name))) {
|
|
169
|
-
for (const surface of toSortedList([...override.allowedSurfaces, ...override.blockedSurfaces])) {
|
|
170
|
-
if (!knownSurfaces.has(surface)) {
|
|
171
|
-
warnings.push(`extension_policy_unknown_surface:${override.name}:${surface}`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
mode,
|
|
177
|
-
trustMode,
|
|
178
|
-
requireProvenance,
|
|
179
|
-
trustedExtensions,
|
|
180
|
-
defaultSandboxProfile,
|
|
181
|
-
allowedExtensions,
|
|
182
|
-
blockedExtensions,
|
|
183
|
-
allowedCapabilities,
|
|
184
|
-
blockedCapabilities,
|
|
185
|
-
allowedSurfaces,
|
|
186
|
-
blockedSurfaces,
|
|
187
|
-
allowedCommands,
|
|
188
|
-
blockedCommands,
|
|
189
|
-
allowedActions,
|
|
190
|
-
blockedActions,
|
|
191
|
-
allowedServices,
|
|
192
|
-
blockedServices,
|
|
193
|
-
overridesByName,
|
|
194
|
-
warnings: [...new Set(warnings)].sort((left, right) => left.localeCompare(right)),
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
function serializeExtensionPolicy(policy) {
|
|
198
|
-
const overrides = [...policy.overridesByName.values()]
|
|
199
|
-
.sort((left, right) => left.name.localeCompare(right.name))
|
|
200
|
-
.map((override) => ({
|
|
201
|
-
name: override.name,
|
|
202
|
-
...(override.disabled ? { disabled: true } : {}),
|
|
203
|
-
...(override.requireTrusted ? { require_trusted: true } : {}),
|
|
204
|
-
...(override.requireProvenance ? { require_provenance: true } : {}),
|
|
205
|
-
...(override.sandboxProfile ? { sandbox_profile: override.sandboxProfile } : {}),
|
|
206
|
-
...(override.allowedCapabilities.size > 0 ? { allowed_capabilities: toSortedList(override.allowedCapabilities) } : {}),
|
|
207
|
-
...(override.blockedCapabilities.size > 0 ? { blocked_capabilities: toSortedList(override.blockedCapabilities) } : {}),
|
|
208
|
-
...(override.allowedSurfaces.size > 0 ? { allowed_surfaces: toSortedList(override.allowedSurfaces) } : {}),
|
|
209
|
-
...(override.blockedSurfaces.size > 0 ? { blocked_surfaces: toSortedList(override.blockedSurfaces) } : {}),
|
|
210
|
-
...(override.allowedCommands.size > 0 ? { allowed_commands: toSortedList(override.allowedCommands) } : {}),
|
|
211
|
-
...(override.blockedCommands.size > 0 ? { blocked_commands: toSortedList(override.blockedCommands) } : {}),
|
|
212
|
-
...(override.allowedActions.size > 0 ? { allowed_actions: toSortedList(override.allowedActions) } : {}),
|
|
213
|
-
...(override.blockedActions.size > 0 ? { blocked_actions: toSortedList(override.blockedActions) } : {}),
|
|
214
|
-
...(override.allowedServices.size > 0 ? { allowed_services: toSortedList(override.allowedServices) } : {}),
|
|
215
|
-
...(override.blockedServices.size > 0 ? { blocked_services: toSortedList(override.blockedServices) } : {}),
|
|
216
|
-
}));
|
|
217
|
-
return {
|
|
218
|
-
mode: policy.mode,
|
|
219
|
-
trust_mode: policy.trustMode,
|
|
220
|
-
require_provenance: policy.requireProvenance,
|
|
221
|
-
trusted_extensions: toSortedList(policy.trustedExtensions),
|
|
222
|
-
default_sandbox_profile: policy.defaultSandboxProfile,
|
|
223
|
-
allowed_extensions: toSortedList(policy.allowedExtensions),
|
|
224
|
-
blocked_extensions: toSortedList(policy.blockedExtensions),
|
|
225
|
-
allowed_capabilities: toSortedList(policy.allowedCapabilities),
|
|
226
|
-
blocked_capabilities: toSortedList(policy.blockedCapabilities),
|
|
227
|
-
allowed_surfaces: toSortedList(policy.allowedSurfaces),
|
|
228
|
-
blocked_surfaces: toSortedList(policy.blockedSurfaces),
|
|
229
|
-
allowed_commands: toSortedList(policy.allowedCommands),
|
|
230
|
-
blocked_commands: toSortedList(policy.blockedCommands),
|
|
231
|
-
allowed_actions: toSortedList(policy.allowedActions),
|
|
232
|
-
blocked_actions: toSortedList(policy.blockedActions),
|
|
233
|
-
allowed_services: toSortedList(policy.allowedServices),
|
|
234
|
-
blocked_services: toSortedList(policy.blockedServices),
|
|
235
|
-
extension_overrides: overrides,
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
function hydrateExtensionPolicy(policy) {
|
|
239
|
-
const overridesByName = new Map();
|
|
240
|
-
for (const rawOverride of policy.extension_overrides ?? []) {
|
|
241
|
-
const name = normalizePolicyName(rawOverride.name);
|
|
242
|
-
if (name.length === 0) {
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
245
|
-
overridesByName.set(name, {
|
|
246
|
-
name,
|
|
247
|
-
disabled: rawOverride.disabled === true,
|
|
248
|
-
requireTrusted: rawOverride.require_trusted === true,
|
|
249
|
-
requireProvenance: rawOverride.require_provenance === true,
|
|
250
|
-
sandboxProfile: rawOverride.sandbox_profile !== undefined
|
|
251
|
-
? normalizePolicySandboxProfile(rawOverride.sandbox_profile)
|
|
252
|
-
: undefined,
|
|
253
|
-
allowedCapabilities: normalizePolicyStringSet(rawOverride.allowed_capabilities),
|
|
254
|
-
blockedCapabilities: normalizePolicyStringSet(rawOverride.blocked_capabilities),
|
|
255
|
-
allowedSurfaces: normalizePolicySurfaceSet(rawOverride.allowed_surfaces),
|
|
256
|
-
blockedSurfaces: normalizePolicySurfaceSet(rawOverride.blocked_surfaces),
|
|
257
|
-
allowedCommands: normalizePolicyStringSet(rawOverride.allowed_commands),
|
|
258
|
-
blockedCommands: normalizePolicyStringSet(rawOverride.blocked_commands),
|
|
259
|
-
allowedActions: normalizePolicyStringSet(rawOverride.allowed_actions),
|
|
260
|
-
blockedActions: normalizePolicyStringSet(rawOverride.blocked_actions),
|
|
261
|
-
allowedServices: normalizePolicyStringSet(rawOverride.allowed_services),
|
|
262
|
-
blockedServices: normalizePolicyStringSet(rawOverride.blocked_services),
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
return {
|
|
266
|
-
mode: normalizePolicyMode(policy.mode),
|
|
267
|
-
trustMode: normalizePolicyTrustMode(policy.trust_mode),
|
|
268
|
-
requireProvenance: policy.require_provenance === true,
|
|
269
|
-
trustedExtensions: normalizePolicyStringSet(policy.trusted_extensions),
|
|
270
|
-
defaultSandboxProfile: normalizePolicySandboxProfile(policy.default_sandbox_profile),
|
|
271
|
-
allowedExtensions: normalizePolicyStringSet(policy.allowed_extensions),
|
|
272
|
-
blockedExtensions: normalizePolicyStringSet(policy.blocked_extensions),
|
|
273
|
-
allowedCapabilities: normalizePolicyStringSet(policy.allowed_capabilities),
|
|
274
|
-
blockedCapabilities: normalizePolicyStringSet(policy.blocked_capabilities),
|
|
275
|
-
allowedSurfaces: normalizePolicySurfaceSet(policy.allowed_surfaces),
|
|
276
|
-
blockedSurfaces: normalizePolicySurfaceSet(policy.blocked_surfaces),
|
|
277
|
-
allowedCommands: normalizePolicyStringSet(policy.allowed_commands),
|
|
278
|
-
blockedCommands: normalizePolicyStringSet(policy.blocked_commands),
|
|
279
|
-
allowedActions: normalizePolicyStringSet(policy.allowed_actions),
|
|
280
|
-
blockedActions: normalizePolicyStringSet(policy.blocked_actions),
|
|
281
|
-
allowedServices: normalizePolicyStringSet(policy.allowed_services),
|
|
282
|
-
blockedServices: normalizePolicyStringSet(policy.blocked_services),
|
|
283
|
-
overridesByName,
|
|
284
|
-
warnings: [],
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
function resolvePolicyOverride(policy, extensionName) {
|
|
288
|
-
return policy.overridesByName.get(normalizePolicyName(extensionName)) ?? null;
|
|
289
|
-
}
|
|
290
|
-
function evaluatePolicySet(allowed, blocked, value, notAllowlistedReason, blockedReason) {
|
|
291
|
-
if (blocked.has(value)) {
|
|
292
|
-
return blockedReason;
|
|
293
|
-
}
|
|
294
|
-
if (allowed.size > 0 && !allowed.has(value)) {
|
|
295
|
-
return notAllowlistedReason;
|
|
296
|
-
}
|
|
297
|
-
return null;
|
|
298
|
-
}
|
|
299
|
-
function resolvePolicyCapabilityReason(policy, extension, capability) {
|
|
300
|
-
const normalizedCapability = capability.trim().toLowerCase();
|
|
301
|
-
const override = resolvePolicyOverride(policy, extension.name);
|
|
302
|
-
const allowed = override && override.allowedCapabilities.size > 0 ? override.allowedCapabilities : policy.allowedCapabilities;
|
|
303
|
-
const blocked = new Set([
|
|
304
|
-
...policy.blockedCapabilities,
|
|
305
|
-
...(override ? override.blockedCapabilities : []),
|
|
306
|
-
]);
|
|
307
|
-
return evaluatePolicySet(allowed, blocked, normalizedCapability, "capability_not_allowlisted", "capability_blocked");
|
|
308
|
-
}
|
|
309
|
-
function resolvePolicySurfaceReason(policy, extension, surface) {
|
|
310
|
-
const override = resolvePolicyOverride(policy, extension.name);
|
|
311
|
-
const allowed = override && override.allowedSurfaces.size > 0 ? override.allowedSurfaces : policy.allowedSurfaces;
|
|
312
|
-
const blocked = new Set([
|
|
313
|
-
...policy.blockedSurfaces,
|
|
314
|
-
...(override ? override.blockedSurfaces : []),
|
|
315
|
-
]);
|
|
316
|
-
return evaluatePolicySet(allowed, blocked, surface, "surface_not_allowlisted", "surface_blocked");
|
|
317
|
-
}
|
|
318
|
-
function resolvePolicyCommandReason(policy, extension, command) {
|
|
319
|
-
const normalizedCommand = normalizeCommandName(command);
|
|
320
|
-
if (normalizedCommand.length === 0) {
|
|
321
|
-
return null;
|
|
322
|
-
}
|
|
323
|
-
const override = resolvePolicyOverride(policy, extension.name);
|
|
324
|
-
const allowed = override && override.allowedCommands.size > 0 ? override.allowedCommands : policy.allowedCommands;
|
|
325
|
-
const blocked = new Set([
|
|
326
|
-
...policy.blockedCommands,
|
|
327
|
-
...(override ? override.blockedCommands : []),
|
|
328
|
-
]);
|
|
329
|
-
return evaluatePolicySet(allowed, blocked, normalizedCommand, "command_not_allowlisted", "command_blocked");
|
|
330
|
-
}
|
|
331
|
-
function resolvePolicyActionReason(policy, extension, action) {
|
|
332
|
-
const normalizedAction = normalizePolicyName(action).replace(/\s+/g, "-");
|
|
333
|
-
if (normalizedAction.length === 0) {
|
|
334
|
-
return null;
|
|
335
|
-
}
|
|
336
|
-
const override = resolvePolicyOverride(policy, extension.name);
|
|
337
|
-
const allowed = override && override.allowedActions.size > 0 ? override.allowedActions : policy.allowedActions;
|
|
338
|
-
const blocked = new Set([
|
|
339
|
-
...policy.blockedActions,
|
|
340
|
-
...(override ? override.blockedActions : []),
|
|
341
|
-
]);
|
|
342
|
-
return evaluatePolicySet(allowed, blocked, normalizedAction, "action_not_allowlisted", "action_blocked");
|
|
343
|
-
}
|
|
344
|
-
function resolvePolicyServiceReason(policy, extension, service) {
|
|
345
|
-
const normalizedService = normalizePolicyName(service);
|
|
346
|
-
if (normalizedService.length === 0) {
|
|
347
|
-
return null;
|
|
348
|
-
}
|
|
349
|
-
const override = resolvePolicyOverride(policy, extension.name);
|
|
350
|
-
const allowed = override && override.allowedServices.size > 0 ? override.allowedServices : policy.allowedServices;
|
|
351
|
-
const blocked = new Set([
|
|
352
|
-
...policy.blockedServices,
|
|
353
|
-
...(override ? override.blockedServices : []),
|
|
354
|
-
]);
|
|
355
|
-
return evaluatePolicySet(allowed, blocked, normalizedService, "service_not_allowlisted", "service_blocked");
|
|
356
|
-
}
|
|
357
|
-
function resolvePolicyExtensionReason(policy, extension) {
|
|
358
|
-
const name = normalizePolicyName(extension.name);
|
|
359
|
-
const override = resolvePolicyOverride(policy, extension.name);
|
|
360
|
-
if (override?.disabled === true) {
|
|
361
|
-
return "extension_override_disabled";
|
|
362
|
-
}
|
|
363
|
-
return evaluatePolicySet(policy.allowedExtensions, policy.blockedExtensions, name, "extension_not_allowlisted", "extension_blocked");
|
|
364
|
-
}
|
|
365
|
-
function resolvePolicyTrustReason(policy, extension) {
|
|
366
|
-
if (policy.trustMode === "off") {
|
|
367
|
-
return null;
|
|
368
|
-
}
|
|
369
|
-
const override = resolvePolicyOverride(policy, extension.name);
|
|
370
|
-
const name = normalizePolicyName(extension.name);
|
|
371
|
-
const trusted = extension.trusted === true;
|
|
372
|
-
const provenanceVerified = extension.provenanceVerified === true;
|
|
373
|
-
if (policy.trustedExtensions.size > 0 && !policy.trustedExtensions.has(name)) {
|
|
374
|
-
return "extension_not_trusted";
|
|
375
|
-
}
|
|
376
|
-
if ((override?.requireTrusted === true || policy.trustMode === "warn" || policy.trustMode === "enforce") && !trusted) {
|
|
377
|
-
return "extension_untrusted";
|
|
378
|
-
}
|
|
379
|
-
if ((policy.requireProvenance || override?.requireProvenance === true) && !provenanceVerified) {
|
|
380
|
-
return "provenance_missing_or_unverified";
|
|
381
|
-
}
|
|
382
|
-
return null;
|
|
383
|
-
}
|
|
384
|
-
function resolvePolicySandboxReason(policy, extension) {
|
|
385
|
-
if (policy.mode === "off") {
|
|
386
|
-
return null;
|
|
387
|
-
}
|
|
388
|
-
const override = resolvePolicyOverride(policy, extension.name);
|
|
389
|
-
const profile = override?.sandboxProfile ?? extension.sandboxProfile ?? policy.defaultSandboxProfile;
|
|
390
|
-
if (profile === "none") {
|
|
391
|
-
return null;
|
|
392
|
-
}
|
|
393
|
-
const permissions = extension.permissions;
|
|
394
|
-
if (!permissions) {
|
|
395
|
-
return "sandbox_permissions_missing";
|
|
396
|
-
}
|
|
397
|
-
const hasPermission = (name) => permissions[name] === true;
|
|
398
|
-
if (profile === "restricted") {
|
|
399
|
-
if (hasPermission("process_spawn")) {
|
|
400
|
-
return "sandbox_restricted_disallows_process_spawn";
|
|
401
|
-
}
|
|
402
|
-
if (hasPermission("env_write")) {
|
|
403
|
-
return "sandbox_restricted_disallows_env_write";
|
|
404
|
-
}
|
|
405
|
-
return null;
|
|
406
|
-
}
|
|
407
|
-
if (profile === "strict") {
|
|
408
|
-
if (hasPermission("process_spawn")) {
|
|
409
|
-
return "sandbox_strict_disallows_process_spawn";
|
|
410
|
-
}
|
|
411
|
-
if (hasPermission("network")) {
|
|
412
|
-
return "sandbox_strict_disallows_network";
|
|
413
|
-
}
|
|
414
|
-
if (hasPermission("fs_write")) {
|
|
415
|
-
return "sandbox_strict_disallows_fs_write";
|
|
416
|
-
}
|
|
417
|
-
if (hasPermission("env_write")) {
|
|
418
|
-
return "sandbox_strict_disallows_env_write";
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
return null;
|
|
422
|
-
}
|
|
423
|
-
function buildPolicyWarning(mode, scope, extension, reason, details = {}) {
|
|
424
|
-
const tokens = Object.entries(details)
|
|
425
|
-
.sort((left, right) => left[0].localeCompare(right[0]))
|
|
426
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
427
|
-
.join(":");
|
|
428
|
-
const suffix = tokens.length > 0 ? `:${tokens}` : "";
|
|
429
|
-
return `extension_policy_${mode}_${scope}:${extension.layer}:${extension.name}:reason=${reason}${suffix}`;
|
|
430
|
-
}
|
|
431
|
-
function evaluateExtensionPolicyForExtension(policy, extension) {
|
|
432
|
-
if (policy.mode === "off" && policy.trustMode === "off") {
|
|
433
|
-
return { allowed: true, warning: null };
|
|
434
|
-
}
|
|
435
|
-
const reason = resolvePolicyExtensionReason(policy, extension);
|
|
436
|
-
const trustReason = resolvePolicyTrustReason(policy, extension);
|
|
437
|
-
const sandboxReason = resolvePolicySandboxReason(policy, extension);
|
|
438
|
-
const extensionEnforced = reason && policy.mode === "enforce";
|
|
439
|
-
const trustEnforced = trustReason && policy.trustMode === "enforce";
|
|
440
|
-
const sandboxEnforced = sandboxReason && policy.mode === "enforce";
|
|
441
|
-
if (!reason && !trustReason && !sandboxReason) {
|
|
442
|
-
return { allowed: true, warning: null };
|
|
443
|
-
}
|
|
444
|
-
if (extensionEnforced) {
|
|
445
|
-
return {
|
|
446
|
-
allowed: false,
|
|
447
|
-
warning: buildPolicyWarning("blocked", "extension", extension, reason),
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
|
-
if (trustEnforced) {
|
|
451
|
-
return {
|
|
452
|
-
allowed: false,
|
|
453
|
-
warning: buildPolicyWarning("blocked", "trust", extension, trustReason),
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
if (sandboxEnforced) {
|
|
457
|
-
return {
|
|
458
|
-
allowed: false,
|
|
459
|
-
warning: buildPolicyWarning("blocked", "extension", extension, sandboxReason),
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
if (reason && policy.mode === "warn") {
|
|
463
|
-
return {
|
|
464
|
-
allowed: true,
|
|
465
|
-
warning: buildPolicyWarning("violation", "extension", extension, reason),
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
if (trustReason && policy.trustMode === "warn") {
|
|
469
|
-
return {
|
|
470
|
-
allowed: true,
|
|
471
|
-
warning: buildPolicyWarning("violation", "trust", extension, trustReason),
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
|
-
if (sandboxReason && policy.mode === "warn") {
|
|
475
|
-
return {
|
|
476
|
-
allowed: true,
|
|
477
|
-
warning: buildPolicyWarning("violation", "extension", extension, sandboxReason),
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
return {
|
|
481
|
-
allowed: true,
|
|
482
|
-
warning: null,
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
function evaluateExtensionPolicyForCapability(policy, extension, capability) {
|
|
486
|
-
if (policy.mode === "off") {
|
|
487
|
-
return { allowed: true, warning: null };
|
|
488
|
-
}
|
|
489
|
-
const reason = resolvePolicyCapabilityReason(policy, extension, capability);
|
|
490
|
-
if (!reason) {
|
|
491
|
-
return { allowed: true, warning: null };
|
|
492
|
-
}
|
|
493
|
-
return {
|
|
494
|
-
allowed: policy.mode === "warn",
|
|
495
|
-
warning: buildPolicyWarning(policy.mode === "warn" ? "violation" : "blocked", "capability", extension, reason, { capability: capability.trim().toLowerCase() }),
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
function evaluateExtensionPolicyForRegistration(policy, extension, surface, method, capability, details) {
|
|
499
|
-
if (policy.mode === "off") {
|
|
500
|
-
return { allowed: true, warning: null };
|
|
501
|
-
}
|
|
502
|
-
const capabilityReason = typeof capability === "string" ? resolvePolicyCapabilityReason(policy, extension, capability) : null;
|
|
503
|
-
const surfaceReason = resolvePolicySurfaceReason(policy, extension, surface);
|
|
504
|
-
const commandReason = details?.command ? resolvePolicyCommandReason(policy, extension, details.command) : null;
|
|
505
|
-
const actionReason = details?.action ? resolvePolicyActionReason(policy, extension, details.action) : null;
|
|
506
|
-
const serviceReason = details?.service ? resolvePolicyServiceReason(policy, extension, details.service) : null;
|
|
507
|
-
const reason = capabilityReason ?? surfaceReason ?? commandReason ?? actionReason ?? serviceReason;
|
|
508
|
-
if (!reason) {
|
|
509
|
-
return { allowed: true, warning: null };
|
|
510
|
-
}
|
|
511
|
-
const warningDetails = {
|
|
512
|
-
method: normalizePolicyName(method).replace(/\s+/g, "_"),
|
|
513
|
-
surface,
|
|
514
|
-
};
|
|
515
|
-
if (capability) {
|
|
516
|
-
warningDetails.capability = capability;
|
|
517
|
-
}
|
|
518
|
-
if (details?.command) {
|
|
519
|
-
warningDetails.command = normalizeCommandName(details.command);
|
|
520
|
-
}
|
|
521
|
-
if (details?.action) {
|
|
522
|
-
warningDetails.action = normalizePolicyName(details.action).replace(/\s+/g, "-");
|
|
523
|
-
}
|
|
524
|
-
if (details?.service) {
|
|
525
|
-
warningDetails.service = normalizePolicyName(details.service);
|
|
526
|
-
}
|
|
527
|
-
const warning = buildPolicyWarning(policy.mode === "warn" ? "violation" : "blocked", "registration", extension, reason, warningDetails);
|
|
528
|
-
return {
|
|
529
|
-
allowed: policy.mode === "warn",
|
|
530
|
-
warning,
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
function resolveLegacyExtensionCapabilityAlias(capability) {
|
|
534
|
-
const normalized = capability.trim().toLowerCase();
|
|
535
|
-
if (normalized.length === 0) {
|
|
536
|
-
return null;
|
|
537
|
-
}
|
|
538
|
-
return EXTENSION_CAPABILITY_LEGACY_ALIASES[normalized] ?? null;
|
|
539
|
-
}
|
|
540
|
-
function normalizeManifestCapabilities(rawCapabilities) {
|
|
541
|
-
const normalizedCapabilities = normalizeNames([...rawCapabilities].map((value) => value.toLowerCase()));
|
|
542
|
-
const remappedCapabilities = [];
|
|
543
|
-
const legacyAliases = [];
|
|
544
|
-
for (const capability of normalizedCapabilities) {
|
|
545
|
-
const legacyAliasTarget = resolveLegacyExtensionCapabilityAlias(capability);
|
|
546
|
-
if (legacyAliasTarget) {
|
|
547
|
-
remappedCapabilities.push(legacyAliasTarget);
|
|
548
|
-
legacyAliases.push({
|
|
549
|
-
alias: capability,
|
|
550
|
-
target: legacyAliasTarget,
|
|
551
|
-
});
|
|
552
|
-
continue;
|
|
553
|
-
}
|
|
554
|
-
remappedCapabilities.push(capability);
|
|
555
|
-
}
|
|
556
|
-
const dedupedLegacyAliases = [...new Map(legacyAliases.map((entry) => [`${entry.alias}>${entry.target}`, entry])).values()].sort((left, right) => left.alias.localeCompare(right.alias));
|
|
557
|
-
return {
|
|
558
|
-
capabilities: normalizeNames(remappedCapabilities),
|
|
559
|
-
legacy_aliases: dedupedLegacyAliases,
|
|
560
|
-
};
|
|
561
|
-
}
|
|
562
|
-
function levenshteinDistance(left, right) {
|
|
563
|
-
if (left === right) {
|
|
564
|
-
return 0;
|
|
565
|
-
}
|
|
566
|
-
if (left.length === 0) {
|
|
567
|
-
return right.length;
|
|
568
|
-
}
|
|
569
|
-
if (right.length === 0) {
|
|
570
|
-
return left.length;
|
|
571
|
-
}
|
|
572
|
-
const previous = new Array(right.length + 1);
|
|
573
|
-
const current = new Array(right.length + 1);
|
|
574
|
-
for (let j = 0; j <= right.length; j += 1) {
|
|
575
|
-
previous[j] = j;
|
|
576
|
-
}
|
|
577
|
-
for (let i = 1; i <= left.length; i += 1) {
|
|
578
|
-
current[0] = i;
|
|
579
|
-
for (let j = 1; j <= right.length; j += 1) {
|
|
580
|
-
const substitutionCost = left[i - 1] === right[j - 1] ? 0 : 1;
|
|
581
|
-
current[j] = Math.min(previous[j] + 1, current[j - 1] + 1, previous[j - 1] + substitutionCost);
|
|
582
|
-
}
|
|
583
|
-
for (let j = 0; j <= right.length; j += 1) {
|
|
584
|
-
previous[j] = current[j];
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
return previous[right.length] ?? left.length;
|
|
588
|
-
}
|
|
589
|
-
function suggestKnownExtensionCapability(capability) {
|
|
590
|
-
const normalized = capability.trim().toLowerCase();
|
|
591
|
-
if (normalized.length === 0) {
|
|
592
|
-
return null;
|
|
593
|
-
}
|
|
594
|
-
const legacyAlias = resolveLegacyExtensionCapabilityAlias(normalized);
|
|
595
|
-
if (legacyAlias) {
|
|
596
|
-
return legacyAlias;
|
|
597
|
-
}
|
|
598
|
-
let bestMatch = null;
|
|
599
|
-
let bestDistance = Number.POSITIVE_INFINITY;
|
|
600
|
-
for (const candidate of KNOWN_EXTENSION_CAPABILITIES) {
|
|
601
|
-
const distance = levenshteinDistance(normalized, candidate);
|
|
602
|
-
if (distance < bestDistance) {
|
|
603
|
-
bestDistance = distance;
|
|
604
|
-
bestMatch = candidate;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
const maxDistance = Math.max(1, Math.floor(normalized.length * 0.34));
|
|
608
|
-
return bestMatch !== null && bestDistance <= maxDistance ? bestMatch : null;
|
|
609
|
-
}
|
|
610
|
-
function formatUnknownExtensionCapabilityWarning(layer, name, capability) {
|
|
611
|
-
const allowed = KNOWN_EXTENSION_CAPABILITIES.join(",");
|
|
612
|
-
const suggested = suggestKnownExtensionCapability(capability) ?? "none";
|
|
613
|
-
return `extension_capability_unknown:${layer}:${name}:${capability}:allowed=${allowed}:suggested=${suggested}`;
|
|
614
|
-
}
|
|
615
|
-
function formatLegacyExtensionCapabilityAliasWarning(layer, name, aliases) {
|
|
616
|
-
const aliasesToken = aliases.map((entry) => `${entry.alias}>${entry.target}`).join(",");
|
|
617
|
-
return `extension_capability_legacy_alias:${layer}:${name}:aliases=${aliasesToken}`;
|
|
618
|
-
}
|
|
619
|
-
export function parseUnknownExtensionCapabilityWarning(warning) {
|
|
620
|
-
const match = /^extension_capability_unknown:(global|project):([^:]+):([^:]+):allowed=([^:]+):suggested=([^:]+)$/.exec(warning.trim());
|
|
621
|
-
if (!match) {
|
|
622
|
-
return null;
|
|
623
|
-
}
|
|
624
|
-
const [, layerRaw, name, capability, allowedRaw, suggestedRaw] = match;
|
|
625
|
-
const layer = layerRaw;
|
|
626
|
-
const allowed_capabilities = allowedRaw
|
|
627
|
-
.split(",")
|
|
628
|
-
.map((value) => value.trim())
|
|
629
|
-
.filter((value) => value.length > 0);
|
|
630
|
-
const legacyAlias = resolveLegacyExtensionCapabilityAlias(capability);
|
|
631
|
-
const suggestedFromWarning = suggestedRaw === "none" ? undefined : suggestedRaw;
|
|
632
|
-
const suggested_capability = suggestedFromWarning ?? legacyAlias ?? undefined;
|
|
633
|
-
const suggestion_source = suggested_capability
|
|
634
|
-
? legacyAlias === suggested_capability
|
|
635
|
-
? "legacy_alias"
|
|
636
|
-
: "nearest_match"
|
|
637
|
-
: undefined;
|
|
638
|
-
return {
|
|
639
|
-
layer,
|
|
640
|
-
name,
|
|
641
|
-
capability,
|
|
642
|
-
allowed_capabilities,
|
|
643
|
-
capability_contract_version: EXTENSION_CAPABILITY_CONTRACT_VERSION,
|
|
644
|
-
suggested_capability,
|
|
645
|
-
suggestion_source,
|
|
646
|
-
legacy_alias_target: legacyAlias ?? undefined,
|
|
647
|
-
};
|
|
648
|
-
}
|
|
649
|
-
export function parseLegacyExtensionCapabilityAliasWarning(warning) {
|
|
650
|
-
const match = /^extension_capability_legacy_alias:(global|project):([^:]+):aliases=(.+)$/.exec(warning.trim());
|
|
651
|
-
if (!match) {
|
|
652
|
-
return [];
|
|
653
|
-
}
|
|
654
|
-
const [, layerRaw, name, aliasesRaw] = match;
|
|
655
|
-
const layer = layerRaw;
|
|
656
|
-
const allowedCapabilities = [...KNOWN_EXTENSION_CAPABILITIES];
|
|
657
|
-
const parsed = [];
|
|
658
|
-
for (const token of aliasesRaw.split(",")) {
|
|
659
|
-
const [rawAlias, rawTarget] = token.split(">");
|
|
660
|
-
const alias = rawAlias?.trim();
|
|
661
|
-
const target = rawTarget?.trim().toLowerCase();
|
|
662
|
-
if (!alias || !target || !isKnownExtensionCapability(target)) {
|
|
663
|
-
continue;
|
|
664
|
-
}
|
|
665
|
-
parsed.push({
|
|
666
|
-
layer,
|
|
667
|
-
name,
|
|
668
|
-
capability: alias,
|
|
669
|
-
allowed_capabilities: allowedCapabilities,
|
|
670
|
-
capability_contract_version: EXTENSION_CAPABILITY_CONTRACT_VERSION,
|
|
671
|
-
suggested_capability: target,
|
|
672
|
-
suggestion_source: "legacy_alias",
|
|
673
|
-
legacy_alias_target: target,
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
return parsed;
|
|
677
|
-
}
|
|
678
31
|
function parseManifest(raw) {
|
|
679
32
|
if (typeof raw !== "object" || raw === null) {
|
|
680
33
|
return null;
|
|
@@ -723,7 +76,7 @@ function parseManifest(raw) {
|
|
|
723
76
|
}
|
|
724
77
|
let provenance;
|
|
725
78
|
if ("provenance" in candidate && candidate.provenance !== undefined && candidate.provenance !== null) {
|
|
726
|
-
const provenanceRecord =
|
|
79
|
+
const provenanceRecord = asRecordLoose(candidate.provenance);
|
|
727
80
|
if (!provenanceRecord) {
|
|
728
81
|
return null;
|
|
729
82
|
}
|
|
@@ -753,7 +106,7 @@ function parseManifest(raw) {
|
|
|
753
106
|
}
|
|
754
107
|
let permissions;
|
|
755
108
|
if ("permissions" in candidate && candidate.permissions !== undefined && candidate.permissions !== null) {
|
|
756
|
-
const permissionsRecord =
|
|
109
|
+
const permissionsRecord = asRecordLoose(candidate.permissions);
|
|
757
110
|
if (!permissionsRecord) {
|
|
758
111
|
return null;
|
|
759
112
|
}
|
|
@@ -808,12 +161,6 @@ function parseManifest(raw) {
|
|
|
808
161
|
legacy_capability_aliases: legacyCapabilityAliases.length > 0 ? legacyCapabilityAliases : undefined,
|
|
809
162
|
};
|
|
810
163
|
}
|
|
811
|
-
function asRecord(value) {
|
|
812
|
-
if (typeof value !== "object" || value === null) {
|
|
813
|
-
return null;
|
|
814
|
-
}
|
|
815
|
-
return value;
|
|
816
|
-
}
|
|
817
164
|
function shouldEnable(name, enabled, disabled) {
|
|
818
165
|
if (disabled.has(name)) {
|
|
819
166
|
return false;
|
|
@@ -833,54 +180,6 @@ export function resolveExtensionRoots(pmRoot, cwd = process.cwd()) {
|
|
|
833
180
|
project: path.join(pmRoot, "extensions"),
|
|
834
181
|
};
|
|
835
182
|
}
|
|
836
|
-
export function createEmptyExtensionHookRegistry() {
|
|
837
|
-
return {
|
|
838
|
-
beforeCommand: [],
|
|
839
|
-
afterCommand: [],
|
|
840
|
-
onWrite: [],
|
|
841
|
-
onRead: [],
|
|
842
|
-
onIndex: [],
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
export function createEmptyExtensionCommandRegistry() {
|
|
846
|
-
return {
|
|
847
|
-
overrides: [],
|
|
848
|
-
handlers: [],
|
|
849
|
-
};
|
|
850
|
-
}
|
|
851
|
-
export function createEmptyExtensionParserRegistry() {
|
|
852
|
-
return {
|
|
853
|
-
overrides: [],
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
export function createEmptyExtensionPreflightRegistry() {
|
|
857
|
-
return {
|
|
858
|
-
overrides: [],
|
|
859
|
-
};
|
|
860
|
-
}
|
|
861
|
-
export function createEmptyExtensionServiceRegistry() {
|
|
862
|
-
return {
|
|
863
|
-
overrides: [],
|
|
864
|
-
};
|
|
865
|
-
}
|
|
866
|
-
export function createEmptyExtensionRendererRegistry() {
|
|
867
|
-
return {
|
|
868
|
-
overrides: [],
|
|
869
|
-
};
|
|
870
|
-
}
|
|
871
|
-
export function createEmptyExtensionRegistrationRegistry() {
|
|
872
|
-
return {
|
|
873
|
-
commands: [],
|
|
874
|
-
flags: [],
|
|
875
|
-
item_fields: [],
|
|
876
|
-
item_types: [],
|
|
877
|
-
migrations: [],
|
|
878
|
-
importers: [],
|
|
879
|
-
exporters: [],
|
|
880
|
-
search_providers: [],
|
|
881
|
-
vector_store_adapters: [],
|
|
882
|
-
};
|
|
883
|
-
}
|
|
884
183
|
async function listExtensionDirectories(extensionsRoot) {
|
|
885
184
|
try {
|
|
886
185
|
const entries = await fs.readdir(extensionsRoot, { withFileTypes: true });
|
|
@@ -1182,7 +481,7 @@ export async function loadExtensions(options) {
|
|
|
1182
481
|
};
|
|
1183
482
|
}
|
|
1184
483
|
function resolveActivatableExtension(module) {
|
|
1185
|
-
const moduleRecord =
|
|
484
|
+
const moduleRecord = asRecordLoose(module);
|
|
1186
485
|
if (!moduleRecord) {
|
|
1187
486
|
return null;
|
|
1188
487
|
}
|
|
@@ -1191,7 +490,7 @@ function resolveActivatableExtension(module) {
|
|
|
1191
490
|
activate: moduleRecord.activate,
|
|
1192
491
|
};
|
|
1193
492
|
}
|
|
1194
|
-
const defaultExport =
|
|
493
|
+
const defaultExport = asRecordLoose(moduleRecord.default);
|
|
1195
494
|
if (defaultExport && typeof defaultExport.activate === "function") {
|
|
1196
495
|
return {
|
|
1197
496
|
activate: defaultExport.activate,
|
|
@@ -1199,46 +498,11 @@ function resolveActivatableExtension(module) {
|
|
|
1199
498
|
}
|
|
1200
499
|
return null;
|
|
1201
500
|
}
|
|
1202
|
-
function normalizeCommandName(command) {
|
|
1203
|
-
return command
|
|
1204
|
-
.trim()
|
|
1205
|
-
.toLowerCase()
|
|
1206
|
-
.split(/\s+/)
|
|
1207
|
-
.filter((part) => part.length > 0)
|
|
1208
|
-
.join(" ");
|
|
1209
|
-
}
|
|
1210
|
-
function defaultGlobalOptions() {
|
|
1211
|
-
return {
|
|
1212
|
-
json: false,
|
|
1213
|
-
quiet: false,
|
|
1214
|
-
noExtensions: false,
|
|
1215
|
-
profile: false,
|
|
1216
|
-
};
|
|
1217
|
-
}
|
|
1218
|
-
function cloneCommandOptionsSnapshot(options) {
|
|
1219
|
-
return options ? cloneContextSnapshot(options) : {};
|
|
1220
|
-
}
|
|
1221
|
-
function cloneGlobalOptionsSnapshot(options) {
|
|
1222
|
-
return options ? cloneContextSnapshot(options) : defaultGlobalOptions();
|
|
1223
|
-
}
|
|
1224
|
-
function cloneContextSnapshot(value) {
|
|
1225
|
-
return structuredClone(value);
|
|
1226
|
-
}
|
|
1227
501
|
function isOutputRendererFormat(value) {
|
|
1228
502
|
return value === "toon" || value === "json";
|
|
1229
503
|
}
|
|
1230
|
-
const EXTENSION_SERVICE_NAMES = [
|
|
1231
|
-
"output_format",
|
|
1232
|
-
"error_format",
|
|
1233
|
-
"help_format",
|
|
1234
|
-
"lock_acquire",
|
|
1235
|
-
"lock_release",
|
|
1236
|
-
"history_append",
|
|
1237
|
-
"item_store_write",
|
|
1238
|
-
"item_store_delete",
|
|
1239
|
-
];
|
|
1240
504
|
function isExtensionServiceName(value) {
|
|
1241
|
-
return
|
|
505
|
+
return KNOWN_EXTENSION_SERVICE_NAMES.includes(value);
|
|
1242
506
|
}
|
|
1243
507
|
function assertHookHandler(hookName, hook) {
|
|
1244
508
|
if (typeof hook !== "function") {
|
|
@@ -1742,7 +1006,7 @@ function createExtensionApi(extension, hooks, commands, parsers, preflight, serv
|
|
|
1742
1006
|
assertExtensionCapability(extension, "services", "registerService");
|
|
1743
1007
|
const normalizedService = String(service).trim().toLowerCase();
|
|
1744
1008
|
if (!isExtensionServiceName(normalizedService)) {
|
|
1745
|
-
throw new TypeError(`registerService service must be one of: ${
|
|
1009
|
+
throw new TypeError(`registerService service must be one of: ${KNOWN_EXTENSION_SERVICE_NAMES.join(", ")}`);
|
|
1746
1010
|
}
|
|
1747
1011
|
if (!allowRegistration("services.override", "registerService", "services", { service: normalizedService })) {
|
|
1748
1012
|
return;
|
|
@@ -2000,18 +1264,6 @@ function createExtensionApi(extension, hooks, commands, parsers, preflight, serv
|
|
|
2000
1264
|
},
|
|
2001
1265
|
};
|
|
2002
1266
|
}
|
|
2003
|
-
async function executeRegisteredHooks(entries, hookName, context) {
|
|
2004
|
-
const warnings = [];
|
|
2005
|
-
for (const entry of entries) {
|
|
2006
|
-
try {
|
|
2007
|
-
await entry.run(cloneContextSnapshot(context));
|
|
2008
|
-
}
|
|
2009
|
-
catch {
|
|
2010
|
-
warnings.push(`extension_hook_failed:${entry.layer}:${entry.name}:${hookName}`);
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
|
-
return warnings;
|
|
2014
|
-
}
|
|
2015
1267
|
function getRegistrationCounts(registrations) {
|
|
2016
1268
|
const commandCount = registrations.commands.length;
|
|
2017
1269
|
const flagCount = registrations.flags.reduce((total, entry) => total + entry.flags.length, 0);
|
|
@@ -2200,374 +1452,5 @@ export async function activateExtensions(loadResult) {
|
|
|
2200
1452
|
registration_counts: getRegistrationCounts(registrations),
|
|
2201
1453
|
};
|
|
2202
1454
|
}
|
|
2203
|
-
export async function runBeforeCommandHooks(hooks, context) {
|
|
2204
|
-
return executeRegisteredHooks(hooks.beforeCommand, "beforeCommand", context);
|
|
2205
|
-
}
|
|
2206
|
-
export async function runAfterCommandHooks(hooks, context) {
|
|
2207
|
-
return executeRegisteredHooks(hooks.afterCommand, "afterCommand", context);
|
|
2208
|
-
}
|
|
2209
|
-
export async function runOnWriteHooks(hooks, context) {
|
|
2210
|
-
return executeRegisteredHooks(hooks.onWrite, "onWrite", context);
|
|
2211
|
-
}
|
|
2212
|
-
export async function runOnReadHooks(hooks, context) {
|
|
2213
|
-
return executeRegisteredHooks(hooks.onRead, "onRead", context);
|
|
2214
|
-
}
|
|
2215
|
-
export async function runOnIndexHooks(hooks, context) {
|
|
2216
|
-
return executeRegisteredHooks(hooks.onIndex, "onIndex", context);
|
|
2217
|
-
}
|
|
2218
|
-
export async function runCommandHandler(commands, context) {
|
|
2219
|
-
const command = normalizeCommandName(context.command);
|
|
2220
|
-
if (command.length === 0) {
|
|
2221
|
-
return {
|
|
2222
|
-
handled: false,
|
|
2223
|
-
result: null,
|
|
2224
|
-
warnings: [],
|
|
2225
|
-
};
|
|
2226
|
-
}
|
|
2227
|
-
const matched = [...commands.handlers].reverse().find((entry) => entry.command === command);
|
|
2228
|
-
if (!matched) {
|
|
2229
|
-
return {
|
|
2230
|
-
handled: false,
|
|
2231
|
-
result: null,
|
|
2232
|
-
warnings: [],
|
|
2233
|
-
};
|
|
2234
|
-
}
|
|
2235
|
-
try {
|
|
2236
|
-
const result = await matched.run({
|
|
2237
|
-
command,
|
|
2238
|
-
args: cloneContextSnapshot(context.args),
|
|
2239
|
-
options: cloneContextSnapshot(context.options),
|
|
2240
|
-
global: cloneContextSnapshot(context.global),
|
|
2241
|
-
pm_root: context.pm_root,
|
|
2242
|
-
});
|
|
2243
|
-
return {
|
|
2244
|
-
handled: true,
|
|
2245
|
-
result,
|
|
2246
|
-
warnings: [],
|
|
2247
|
-
};
|
|
2248
|
-
}
|
|
2249
|
-
catch (error) {
|
|
2250
|
-
const exitCode = typeof error === "object" && error !== null && "exitCode" in error
|
|
2251
|
-
? error.exitCode
|
|
2252
|
-
: undefined;
|
|
2253
|
-
if (typeof exitCode === "number" && Number.isFinite(exitCode)) {
|
|
2254
|
-
throw error;
|
|
2255
|
-
}
|
|
2256
|
-
return {
|
|
2257
|
-
handled: false,
|
|
2258
|
-
result: null,
|
|
2259
|
-
warnings: [`extension_command_handler_failed:${matched.layer}:${matched.name}:${matched.command}`],
|
|
2260
|
-
};
|
|
2261
|
-
}
|
|
2262
|
-
}
|
|
2263
|
-
export async function runParserOverride(parsers, context) {
|
|
2264
|
-
const command = normalizeCommandName(context.command);
|
|
2265
|
-
if (command.length === 0) {
|
|
2266
|
-
return {
|
|
2267
|
-
overridden: false,
|
|
2268
|
-
context: {
|
|
2269
|
-
command,
|
|
2270
|
-
args: cloneContextSnapshot(context.args),
|
|
2271
|
-
options: cloneCommandOptionsSnapshot(context.options),
|
|
2272
|
-
global: cloneGlobalOptionsSnapshot(context.global),
|
|
2273
|
-
pm_root: context.pm_root,
|
|
2274
|
-
},
|
|
2275
|
-
warnings: [],
|
|
2276
|
-
};
|
|
2277
|
-
}
|
|
2278
|
-
const matched = [...parsers.overrides].reverse().find((entry) => entry.command === command);
|
|
2279
|
-
if (!matched) {
|
|
2280
|
-
return {
|
|
2281
|
-
overridden: false,
|
|
2282
|
-
context: {
|
|
2283
|
-
command,
|
|
2284
|
-
args: cloneContextSnapshot(context.args),
|
|
2285
|
-
options: cloneCommandOptionsSnapshot(context.options),
|
|
2286
|
-
global: cloneGlobalOptionsSnapshot(context.global),
|
|
2287
|
-
pm_root: context.pm_root,
|
|
2288
|
-
},
|
|
2289
|
-
warnings: [],
|
|
2290
|
-
};
|
|
2291
|
-
}
|
|
2292
|
-
try {
|
|
2293
|
-
const delta = (await Promise.resolve(matched.run({
|
|
2294
|
-
command,
|
|
2295
|
-
args: cloneContextSnapshot(context.args),
|
|
2296
|
-
options: cloneCommandOptionsSnapshot(context.options),
|
|
2297
|
-
global: cloneGlobalOptionsSnapshot(context.global),
|
|
2298
|
-
pm_root: context.pm_root,
|
|
2299
|
-
}))) ?? {};
|
|
2300
|
-
const nextArgs = Array.isArray(delta.args) ? cloneContextSnapshot(delta.args) : cloneContextSnapshot(context.args);
|
|
2301
|
-
const nextOptions = delta.options ? cloneCommandOptionsSnapshot(delta.options) : cloneCommandOptionsSnapshot(context.options);
|
|
2302
|
-
const nextGlobal = delta.global ? cloneGlobalOptionsSnapshot(delta.global) : cloneGlobalOptionsSnapshot(context.global);
|
|
2303
|
-
return {
|
|
2304
|
-
overridden: true,
|
|
2305
|
-
context: {
|
|
2306
|
-
command,
|
|
2307
|
-
args: nextArgs,
|
|
2308
|
-
options: nextOptions,
|
|
2309
|
-
global: nextGlobal,
|
|
2310
|
-
pm_root: context.pm_root,
|
|
2311
|
-
},
|
|
2312
|
-
warnings: [],
|
|
2313
|
-
};
|
|
2314
|
-
}
|
|
2315
|
-
catch {
|
|
2316
|
-
return {
|
|
2317
|
-
overridden: false,
|
|
2318
|
-
context: {
|
|
2319
|
-
command,
|
|
2320
|
-
args: cloneContextSnapshot(context.args),
|
|
2321
|
-
options: cloneCommandOptionsSnapshot(context.options),
|
|
2322
|
-
global: cloneGlobalOptionsSnapshot(context.global),
|
|
2323
|
-
pm_root: context.pm_root,
|
|
2324
|
-
},
|
|
2325
|
-
warnings: [`extension_parser_override_failed:${matched.layer}:${matched.name}:${matched.command}`],
|
|
2326
|
-
};
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
export async function runPreflightOverride(preflight, context) {
|
|
2330
|
-
const matched = [...preflight.overrides].reverse()[0];
|
|
2331
|
-
const baseContext = {
|
|
2332
|
-
command: normalizeCommandName(context.command),
|
|
2333
|
-
args: cloneContextSnapshot(context.args),
|
|
2334
|
-
options: cloneCommandOptionsSnapshot(context.options),
|
|
2335
|
-
global: cloneGlobalOptionsSnapshot(context.global),
|
|
2336
|
-
pm_root: context.pm_root,
|
|
2337
|
-
};
|
|
2338
|
-
const baseDecision = cloneContextSnapshot(context.decision);
|
|
2339
|
-
if (!matched) {
|
|
2340
|
-
return {
|
|
2341
|
-
overridden: false,
|
|
2342
|
-
context: baseContext,
|
|
2343
|
-
decision: baseDecision,
|
|
2344
|
-
warnings: [],
|
|
2345
|
-
};
|
|
2346
|
-
}
|
|
2347
|
-
try {
|
|
2348
|
-
const delta = (await Promise.resolve(matched.run({
|
|
2349
|
-
command: baseContext.command,
|
|
2350
|
-
args: cloneContextSnapshot(baseContext.args),
|
|
2351
|
-
options: cloneCommandOptionsSnapshot(baseContext.options),
|
|
2352
|
-
global: cloneGlobalOptionsSnapshot(baseContext.global),
|
|
2353
|
-
pm_root: baseContext.pm_root,
|
|
2354
|
-
decision: cloneContextSnapshot(baseDecision),
|
|
2355
|
-
}))) ?? {};
|
|
2356
|
-
const nextContext = {
|
|
2357
|
-
command: baseContext.command,
|
|
2358
|
-
args: Array.isArray(delta.args) ? cloneContextSnapshot(delta.args) : baseContext.args,
|
|
2359
|
-
options: delta.options ? cloneCommandOptionsSnapshot(delta.options) : baseContext.options,
|
|
2360
|
-
global: delta.global ? cloneGlobalOptionsSnapshot(delta.global) : baseContext.global,
|
|
2361
|
-
pm_root: baseContext.pm_root,
|
|
2362
|
-
};
|
|
2363
|
-
const nextDecision = {
|
|
2364
|
-
enforce_item_format_gate: typeof delta.enforce_item_format_gate === "boolean"
|
|
2365
|
-
? delta.enforce_item_format_gate
|
|
2366
|
-
: baseDecision.enforce_item_format_gate,
|
|
2367
|
-
run_preflight_item_format_sync: typeof delta.run_preflight_item_format_sync === "boolean"
|
|
2368
|
-
? delta.run_preflight_item_format_sync
|
|
2369
|
-
: baseDecision.run_preflight_item_format_sync,
|
|
2370
|
-
run_extension_migrations: typeof delta.run_extension_migrations === "boolean"
|
|
2371
|
-
? delta.run_extension_migrations
|
|
2372
|
-
: baseDecision.run_extension_migrations,
|
|
2373
|
-
enforce_mandatory_migration_gate: typeof delta.enforce_mandatory_migration_gate === "boolean"
|
|
2374
|
-
? delta.enforce_mandatory_migration_gate
|
|
2375
|
-
: baseDecision.enforce_mandatory_migration_gate,
|
|
2376
|
-
};
|
|
2377
|
-
return {
|
|
2378
|
-
overridden: true,
|
|
2379
|
-
context: nextContext,
|
|
2380
|
-
decision: nextDecision,
|
|
2381
|
-
warnings: [],
|
|
2382
|
-
};
|
|
2383
|
-
}
|
|
2384
|
-
catch {
|
|
2385
|
-
return {
|
|
2386
|
-
overridden: false,
|
|
2387
|
-
context: baseContext,
|
|
2388
|
-
decision: baseDecision,
|
|
2389
|
-
warnings: [`extension_preflight_override_failed:${matched.layer}:${matched.name}`],
|
|
2390
|
-
};
|
|
2391
|
-
}
|
|
2392
|
-
}
|
|
2393
|
-
function resolveDefaultServiceResult(context) {
|
|
2394
|
-
return {
|
|
2395
|
-
handled: false,
|
|
2396
|
-
result: context.payload,
|
|
2397
|
-
warnings: [],
|
|
2398
|
-
};
|
|
2399
|
-
}
|
|
2400
|
-
export function runServiceOverrideSync(services, context) {
|
|
2401
|
-
const matches = [...services.overrides].reverse().filter((entry) => entry.service === context.service);
|
|
2402
|
-
if (matches.length === 0) {
|
|
2403
|
-
return resolveDefaultServiceResult(context);
|
|
2404
|
-
}
|
|
2405
|
-
const warnings = [];
|
|
2406
|
-
for (const matched of matches) {
|
|
2407
|
-
try {
|
|
2408
|
-
const serviceContext = {
|
|
2409
|
-
service: context.service,
|
|
2410
|
-
command: context.command ? normalizeCommandName(context.command) : undefined,
|
|
2411
|
-
args: context.args ? cloneContextSnapshot(context.args) : undefined,
|
|
2412
|
-
options: context.options ? cloneCommandOptionsSnapshot(context.options) : undefined,
|
|
2413
|
-
global: context.global ? cloneGlobalOptionsSnapshot(context.global) : undefined,
|
|
2414
|
-
pm_root: context.pm_root,
|
|
2415
|
-
payload: cloneContextSnapshot(context.payload),
|
|
2416
|
-
};
|
|
2417
|
-
const result = matched.run(serviceContext);
|
|
2418
|
-
if (result instanceof Promise) {
|
|
2419
|
-
warnings.push(`extension_service_override_async_unsupported:${matched.layer}:${matched.name}:${matched.service}`);
|
|
2420
|
-
continue;
|
|
2421
|
-
}
|
|
2422
|
-
if (context.service === "output_format" && (result === null || result === undefined || result === serviceContext.payload)) {
|
|
2423
|
-
continue;
|
|
2424
|
-
}
|
|
2425
|
-
return {
|
|
2426
|
-
handled: true,
|
|
2427
|
-
result,
|
|
2428
|
-
warnings,
|
|
2429
|
-
};
|
|
2430
|
-
}
|
|
2431
|
-
catch {
|
|
2432
|
-
warnings.push(`extension_service_override_failed:${matched.layer}:${matched.name}:${matched.service}`);
|
|
2433
|
-
}
|
|
2434
|
-
}
|
|
2435
|
-
return {
|
|
2436
|
-
handled: false,
|
|
2437
|
-
result: context.payload,
|
|
2438
|
-
warnings,
|
|
2439
|
-
};
|
|
2440
|
-
}
|
|
2441
|
-
export async function runServiceOverride(services, context) {
|
|
2442
|
-
const matches = [...services.overrides].reverse().filter((entry) => entry.service === context.service);
|
|
2443
|
-
if (matches.length === 0) {
|
|
2444
|
-
return resolveDefaultServiceResult(context);
|
|
2445
|
-
}
|
|
2446
|
-
const warnings = [];
|
|
2447
|
-
for (const matched of matches) {
|
|
2448
|
-
try {
|
|
2449
|
-
const serviceContext = {
|
|
2450
|
-
service: context.service,
|
|
2451
|
-
command: context.command ? normalizeCommandName(context.command) : undefined,
|
|
2452
|
-
args: context.args ? cloneContextSnapshot(context.args) : undefined,
|
|
2453
|
-
options: context.options ? cloneCommandOptionsSnapshot(context.options) : undefined,
|
|
2454
|
-
global: context.global ? cloneGlobalOptionsSnapshot(context.global) : undefined,
|
|
2455
|
-
pm_root: context.pm_root,
|
|
2456
|
-
payload: cloneContextSnapshot(context.payload),
|
|
2457
|
-
};
|
|
2458
|
-
const result = await Promise.resolve(matched.run(serviceContext));
|
|
2459
|
-
if (context.service === "output_format" && (result === null || result === undefined || result === serviceContext.payload)) {
|
|
2460
|
-
continue;
|
|
2461
|
-
}
|
|
2462
|
-
return {
|
|
2463
|
-
handled: true,
|
|
2464
|
-
result,
|
|
2465
|
-
warnings,
|
|
2466
|
-
};
|
|
2467
|
-
}
|
|
2468
|
-
catch {
|
|
2469
|
-
warnings.push(`extension_service_override_failed:${matched.layer}:${matched.name}:${matched.service}`);
|
|
2470
|
-
}
|
|
2471
|
-
}
|
|
2472
|
-
return {
|
|
2473
|
-
handled: false,
|
|
2474
|
-
result: context.payload,
|
|
2475
|
-
warnings,
|
|
2476
|
-
};
|
|
2477
|
-
}
|
|
2478
|
-
export function runCommandOverride(commands, context) {
|
|
2479
|
-
const command = normalizeCommandName(context.command);
|
|
2480
|
-
if (command.length === 0) {
|
|
2481
|
-
return {
|
|
2482
|
-
overridden: false,
|
|
2483
|
-
result: context.result,
|
|
2484
|
-
warnings: [],
|
|
2485
|
-
};
|
|
2486
|
-
}
|
|
2487
|
-
const matched = [...commands.overrides].reverse().find((entry) => entry.command === command);
|
|
2488
|
-
if (!matched) {
|
|
2489
|
-
return {
|
|
2490
|
-
overridden: false,
|
|
2491
|
-
result: context.result,
|
|
2492
|
-
warnings: [],
|
|
2493
|
-
};
|
|
2494
|
-
}
|
|
2495
|
-
try {
|
|
2496
|
-
const overrideOptions = cloneCommandOptionsSnapshot(context.options);
|
|
2497
|
-
const overrideGlobal = cloneGlobalOptionsSnapshot(context.global);
|
|
2498
|
-
const overrideResult = matched.run({
|
|
2499
|
-
command,
|
|
2500
|
-
args: cloneContextSnapshot(context.args),
|
|
2501
|
-
options: overrideOptions,
|
|
2502
|
-
global: overrideGlobal,
|
|
2503
|
-
pm_root: context.pm_root,
|
|
2504
|
-
result: cloneContextSnapshot(context.result),
|
|
2505
|
-
});
|
|
2506
|
-
if (overrideResult instanceof Promise) {
|
|
2507
|
-
return {
|
|
2508
|
-
overridden: false,
|
|
2509
|
-
result: context.result,
|
|
2510
|
-
warnings: [`extension_command_override_async_unsupported:${matched.layer}:${matched.name}:${matched.command}`],
|
|
2511
|
-
};
|
|
2512
|
-
}
|
|
2513
|
-
return {
|
|
2514
|
-
overridden: true,
|
|
2515
|
-
result: overrideResult,
|
|
2516
|
-
warnings: [],
|
|
2517
|
-
};
|
|
2518
|
-
}
|
|
2519
|
-
catch {
|
|
2520
|
-
return {
|
|
2521
|
-
overridden: false,
|
|
2522
|
-
result: context.result,
|
|
2523
|
-
warnings: [`extension_command_override_failed:${matched.layer}:${matched.name}:${matched.command}`],
|
|
2524
|
-
};
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
export function runRendererOverride(renderers, context) {
|
|
2528
|
-
const matched = [...renderers.overrides].reverse().find((entry) => entry.format === context.format);
|
|
2529
|
-
if (!matched) {
|
|
2530
|
-
return {
|
|
2531
|
-
overridden: false,
|
|
2532
|
-
rendered: null,
|
|
2533
|
-
warnings: [],
|
|
2534
|
-
};
|
|
2535
|
-
}
|
|
2536
|
-
try {
|
|
2537
|
-
const rendererCommand = typeof context.command === "string" ? normalizeCommandName(context.command) : "";
|
|
2538
|
-
const rendererArgs = Array.isArray(context.args) ? cloneContextSnapshot(context.args) : [];
|
|
2539
|
-
const rendererOptions = cloneCommandOptionsSnapshot(context.options);
|
|
2540
|
-
const rendererGlobal = cloneGlobalOptionsSnapshot(context.global);
|
|
2541
|
-
const rendererPmRoot = typeof context.pm_root === "string" ? context.pm_root : "";
|
|
2542
|
-
const rendered = matched.run({
|
|
2543
|
-
format: context.format,
|
|
2544
|
-
command: rendererCommand,
|
|
2545
|
-
args: rendererArgs,
|
|
2546
|
-
options: rendererOptions,
|
|
2547
|
-
global: rendererGlobal,
|
|
2548
|
-
pm_root: rendererPmRoot,
|
|
2549
|
-
result: cloneContextSnapshot(context.result),
|
|
2550
|
-
});
|
|
2551
|
-
if (typeof rendered !== "string") {
|
|
2552
|
-
return {
|
|
2553
|
-
overridden: false,
|
|
2554
|
-
rendered: null,
|
|
2555
|
-
warnings: [`extension_renderer_invalid_result:${matched.layer}:${matched.name}:${matched.format}`],
|
|
2556
|
-
};
|
|
2557
|
-
}
|
|
2558
|
-
return {
|
|
2559
|
-
overridden: true,
|
|
2560
|
-
rendered,
|
|
2561
|
-
warnings: [],
|
|
2562
|
-
};
|
|
2563
|
-
}
|
|
2564
|
-
catch {
|
|
2565
|
-
return {
|
|
2566
|
-
overridden: false,
|
|
2567
|
-
rendered: null,
|
|
2568
|
-
warnings: [`extension_renderer_failed:${matched.layer}:${matched.name}:${matched.format}`],
|
|
2569
|
-
};
|
|
2570
|
-
}
|
|
2571
|
-
}
|
|
2572
1455
|
//# sourceMappingURL=loader.js.map
|
|
2573
|
-
//# debugId=
|
|
1456
|
+
//# debugId=4fba8687-0797-5479-afc8-12f1a2e5a954
|