@unbrained/pm-cli 2026.5.12 → 2026.5.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/CHANGELOG.md +11 -0
- package/PRD.md +7 -28
- package/README.md +2 -9
- package/dist/cli/commander-usage.js +27 -0
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/activity.js +19 -4
- package/dist/cli/commands/activity.js.map +1 -1
- package/dist/cli/commands/calendar.js +5 -2
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/contracts.js +56 -18
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.js +58 -3
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/extension.d.ts +5 -1
- package/dist/cli/commands/extension.js +245 -39
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/index.d.ts +0 -8
- package/dist/cli/commands/index.js +0 -8
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/reindex.d.ts +8 -0
- package/dist/cli/commands/reindex.js +96 -23
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/search.js +51 -25
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/help-content.js +17 -18
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/main.js +73 -7
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +24 -142
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +49 -257
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +29 -198
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +32 -133
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.d.ts +2 -2
- package/dist/cli/registration-helpers.js +1 -19
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/core/extensions/loader.js +7 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/packages/manifest.d.ts +26 -1
- package/dist/core/packages/manifest.js +82 -0
- package/dist/core/packages/manifest.js.map +1 -1
- package/dist/core/search/embedding-batches.d.ts +13 -1
- package/dist/core/search/embedding-batches.js +19 -1
- package/dist/core/search/embedding-batches.js.map +1 -1
- package/dist/core/store/front-matter-cache.d.ts +8 -1
- package/dist/core/store/front-matter-cache.js +20 -11
- package/dist/core/store/front-matter-cache.js.map +1 -1
- package/dist/mcp/server.d.ts +8 -0
- package/dist/mcp/server.js +93 -43
- package/dist/mcp/server.js.map +1 -1
- package/dist/sdk/cli-contracts/commander-mutation-options.d.ts +7 -0
- package/dist/sdk/cli-contracts/commander-mutation-options.js +477 -0
- package/dist/sdk/cli-contracts/commander-mutation-options.js.map +1 -0
- package/dist/sdk/cli-contracts/commander-types.d.ts +21 -0
- package/dist/sdk/cli-contracts/commander-types.js +92 -0
- package/dist/sdk/cli-contracts/commander-types.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +6 -17
- package/dist/sdk/cli-contracts.js +19 -262
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/index.d.ts +2 -1
- package/dist/sdk/index.js +1 -0
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runtime.d.ts +29 -0
- package/dist/sdk/runtime.js +28 -0
- package/dist/sdk/runtime.js.map +1 -0
- package/docs/COMMANDS.md +3 -0
- package/docs/EXTENSIONS.md +60 -35
- package/docs/QUICKSTART.md +1 -0
- package/docs/RELEASING.md +4 -2
- package/docs/SDK.md +78 -441
- package/package.json +4 -3
- package/packages/pm-beads/extensions/beads/index.js +90 -101
- package/packages/pm-beads/extensions/beads/index.ts +2 -2
- package/packages/pm-beads/extensions/beads/runtime.js +2 -17
- package/packages/pm-beads/extensions/beads/runtime.ts +41 -18
- package/packages/pm-beads/package.json +33 -0
- package/packages/pm-calendar/README.md +13 -0
- package/packages/pm-calendar/extensions/calendar/index.js +56 -0
- package/packages/pm-calendar/extensions/calendar/index.ts +62 -0
- package/packages/pm-calendar/extensions/calendar/manifest.json +7 -0
- package/packages/pm-calendar/extensions/calendar/runtime.js +95 -0
- package/packages/pm-calendar/extensions/calendar/runtime.ts +104 -0
- package/packages/pm-calendar/package.json +51 -0
- package/packages/pm-governance-audit/README.md +23 -0
- package/packages/pm-governance-audit/extensions/governance-audit/index.js +117 -0
- package/packages/pm-governance-audit/extensions/governance-audit/index.ts +118 -0
- package/packages/pm-governance-audit/extensions/governance-audit/manifest.json +7 -0
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +159 -0
- package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +176 -0
- package/packages/pm-governance-audit/package.json +52 -0
- package/packages/pm-guide-shell/README.md +23 -0
- package/packages/pm-guide-shell/extensions/guide-shell/index.js +76 -0
- package/packages/pm-guide-shell/extensions/guide-shell/index.ts +81 -0
- package/packages/pm-guide-shell/extensions/guide-shell/manifest.json +7 -0
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +263 -0
- package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +327 -0
- package/packages/pm-guide-shell/package.json +52 -0
- package/packages/pm-linked-test-adapters/README.md +24 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/index.js +101 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/index.ts +102 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/manifest.json +7 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +142 -0
- package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +173 -0
- package/packages/pm-linked-test-adapters/package.json +53 -0
- package/packages/pm-search-advanced/README.md +27 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.js +93 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.ts +94 -0
- package/packages/pm-search-advanced/extensions/search-advanced/manifest.json +7 -0
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +120 -0
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +144 -0
- package/packages/pm-search-advanced/package.json +54 -0
- package/packages/pm-templates/README.md +20 -0
- package/packages/pm-templates/extensions/templates/index.js +101 -0
- package/packages/pm-templates/extensions/templates/index.ts +109 -0
- package/packages/pm-templates/extensions/templates/manifest.json +7 -0
- package/packages/pm-templates/extensions/templates/runtime.js +226 -0
- package/packages/pm-templates/extensions/templates/runtime.ts +283 -0
- package/packages/pm-templates/package.json +50 -0
- package/packages/pm-todos/extensions/todos/index.js +105 -116
- package/packages/pm-todos/extensions/todos/index.ts +3 -2
- package/packages/pm-todos/extensions/todos/runtime.js +2 -17
- package/packages/pm-todos/extensions/todos/runtime.ts +40 -18
- package/packages/pm-todos/package.json +34 -0
- package/plugins/pm-cli-claude/scripts/pm-mcp-server.mjs +4 -2
- package/plugins/pm-cli-codex/scripts/pm-mcp-server.mjs +4 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { GlobalOptions } from "../../core/shared/command-types.js";
|
|
2
|
-
export type ExtensionCommandAction = "install" | "uninstall" | "explore" | "manage" | "reload" | "doctor" | "adopt" | "adopt-all" | "activate" | "deactivate" | "init";
|
|
2
|
+
export type ExtensionCommandAction = "install" | "uninstall" | "explore" | "manage" | "reload" | "doctor" | "catalog" | "adopt" | "adopt-all" | "activate" | "deactivate" | "init";
|
|
3
3
|
export type ExtensionScope = "project" | "global";
|
|
4
4
|
export type ExtensionActivationStatus = "ok" | "failed" | "not_loaded" | "unknown";
|
|
5
5
|
export interface ExtensionCommandOptions {
|
|
@@ -9,6 +9,7 @@ export interface ExtensionCommandOptions {
|
|
|
9
9
|
manage?: boolean;
|
|
10
10
|
reload?: boolean;
|
|
11
11
|
doctor?: boolean;
|
|
12
|
+
catalog?: boolean;
|
|
12
13
|
init?: boolean;
|
|
13
14
|
scaffold?: boolean;
|
|
14
15
|
strictExit?: boolean;
|
|
@@ -28,6 +29,7 @@ export interface ExtensionCommandOptions {
|
|
|
28
29
|
watch?: boolean;
|
|
29
30
|
runtimeProbe?: boolean;
|
|
30
31
|
fixManagedState?: boolean;
|
|
32
|
+
vocabulary?: "extension" | "package";
|
|
31
33
|
}
|
|
32
34
|
export interface ManagedExtensionSource {
|
|
33
35
|
kind: "local" | "github" | "npm";
|
|
@@ -97,6 +99,8 @@ export interface ManagedExtensionSummary {
|
|
|
97
99
|
enabled: boolean;
|
|
98
100
|
runtime_active: boolean | null;
|
|
99
101
|
activation_status: ExtensionActivationStatus;
|
|
102
|
+
command_paths?: string[];
|
|
103
|
+
action_paths?: string[];
|
|
100
104
|
managed: boolean;
|
|
101
105
|
source?: ManagedExtensionSource;
|
|
102
106
|
update_available?: boolean | null;
|
|
@@ -7,7 +7,7 @@ import { promisify } from "node:util";
|
|
|
7
7
|
import { activateExtensions, loadExtensions, nextExtensionReloadToken } from "../../core/extensions/index.js";
|
|
8
8
|
import { EXTENSION_CAPABILITY_CONTRACT, KNOWN_EXTENSION_CAPABILITIES, parseLegacyExtensionCapabilityAliasWarning, parseUnknownExtensionCapabilityWarning, resolveExtensionRoots, } from "../../core/extensions/loader.js";
|
|
9
9
|
import { pathExists } from "../../core/fs/fs-utils.js";
|
|
10
|
-
import { collectPackageExtensionDirectories } from "../../core/packages/manifest.js";
|
|
10
|
+
import { PM_PACKAGE_RESOURCE_KINDS, collectPackageExtensionDirectories, readPmPackageManifest, } from "../../core/packages/manifest.js";
|
|
11
11
|
import { EXIT_CODE } from "../../core/shared/constants.js";
|
|
12
12
|
import { PmCliError } from "../../core/shared/errors.js";
|
|
13
13
|
import { nowIso } from "../../core/shared/time.js";
|
|
@@ -18,7 +18,7 @@ const DEFAULT_EXTENSION_PRIORITY = 100;
|
|
|
18
18
|
const MANAGED_EXTENSION_STATE_FILENAME = ".managed-extensions.json";
|
|
19
19
|
const MANAGED_EXTENSION_STATE_VERSION = 1;
|
|
20
20
|
const PM_PACKAGE_ROOT_ENV = "PM_CLI_PACKAGE_ROOT";
|
|
21
|
-
const
|
|
21
|
+
const LEGACY_BUNDLED_PACKAGE_ALIASES = {
|
|
22
22
|
beads: {
|
|
23
23
|
package_directory: "pm-beads",
|
|
24
24
|
legacy_extension_directory: "beads",
|
|
@@ -41,15 +41,15 @@ function resolvePackageRootCandidates() {
|
|
|
41
41
|
}
|
|
42
42
|
async function resolveBundledExtensionAliasSource(input) {
|
|
43
43
|
const normalized = input.trim().toLowerCase();
|
|
44
|
-
const
|
|
44
|
+
const packageRoot = await resolveBundledPackageRoot(normalized);
|
|
45
|
+
if (packageRoot) {
|
|
46
|
+
return packageRoot;
|
|
47
|
+
}
|
|
48
|
+
const alias = LEGACY_BUNDLED_PACKAGE_ALIASES[normalized];
|
|
45
49
|
if (!alias) {
|
|
46
50
|
return null;
|
|
47
51
|
}
|
|
48
52
|
for (const packageRoot of resolvePackageRootCandidates()) {
|
|
49
|
-
const packagePath = path.join(packageRoot, "packages", alias.package_directory);
|
|
50
|
-
if (await pathExists(path.join(packagePath, "package.json"))) {
|
|
51
|
-
return packagePath;
|
|
52
|
-
}
|
|
53
53
|
const legacyExtensionPath = path.join(packageRoot, ".agents", "pm", "extensions", alias.legacy_extension_directory);
|
|
54
54
|
if (await pathExists(path.join(legacyExtensionPath, "manifest.json"))) {
|
|
55
55
|
return legacyExtensionPath;
|
|
@@ -60,8 +60,67 @@ async function resolveBundledExtensionAliasSource(input) {
|
|
|
60
60
|
function isBundledPackageInstallAllTarget(input) {
|
|
61
61
|
return BUNDLED_PACKAGE_INSTALL_ALL_TARGETS.has(input.trim().toLowerCase());
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
return
|
|
63
|
+
function derivePackageAlias(packageDirectory) {
|
|
64
|
+
return packageDirectory.replace(/^pm-/i, "").trim().toLowerCase();
|
|
65
|
+
}
|
|
66
|
+
async function collectBundledPackageEntries() {
|
|
67
|
+
const entriesByAlias = new Map();
|
|
68
|
+
for (const packageRoot of resolvePackageRootCandidates()) {
|
|
69
|
+
const packagesRoot = path.join(packageRoot, "packages");
|
|
70
|
+
if (!(await pathExists(packagesRoot))) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const entries = await fs.readdir(packagesRoot, { withFileTypes: true });
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
if (!entry.isDirectory() || !entry.name.startsWith("pm-")) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const candidateRoot = path.join(packagesRoot, entry.name);
|
|
79
|
+
if (!(await pathExists(path.join(candidateRoot, "package.json")))) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const manifest = await readPmPackageManifest(candidateRoot);
|
|
83
|
+
const aliases = manifest.aliases && manifest.aliases.length > 0
|
|
84
|
+
? manifest.aliases
|
|
85
|
+
: [derivePackageAlias(entry.name)];
|
|
86
|
+
for (const alias of aliases) {
|
|
87
|
+
const normalizedAlias = alias.trim().toLowerCase();
|
|
88
|
+
if (normalizedAlias.length === 0 || entriesByAlias.has(normalizedAlias)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
entriesByAlias.set(normalizedAlias, {
|
|
92
|
+
alias: normalizedAlias,
|
|
93
|
+
package_directory: entry.name,
|
|
94
|
+
package_root: candidateRoot,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (const [alias, legacy] of Object.entries(LEGACY_BUNDLED_PACKAGE_ALIASES)) {
|
|
100
|
+
if (entriesByAlias.has(alias)) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
for (const packageRoot of resolvePackageRootCandidates()) {
|
|
104
|
+
const packagePath = path.join(packageRoot, "packages", legacy.package_directory);
|
|
105
|
+
if (await pathExists(path.join(packagePath, "package.json"))) {
|
|
106
|
+
entriesByAlias.set(alias, {
|
|
107
|
+
alias,
|
|
108
|
+
package_directory: legacy.package_directory,
|
|
109
|
+
package_root: packagePath,
|
|
110
|
+
});
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return [...entriesByAlias.values()].sort((left, right) => left.alias.localeCompare(right.alias));
|
|
116
|
+
}
|
|
117
|
+
async function listBundledPackageAliases() {
|
|
118
|
+
return (await collectBundledPackageEntries()).map((entry) => entry.alias);
|
|
119
|
+
}
|
|
120
|
+
async function resolveBundledPackageRoot(alias) {
|
|
121
|
+
const normalized = alias.trim().toLowerCase();
|
|
122
|
+
const entry = (await collectBundledPackageEntries()).find((candidate) => candidate.alias === normalized);
|
|
123
|
+
return entry?.package_root ?? null;
|
|
65
124
|
}
|
|
66
125
|
function normalizeStringList(values) {
|
|
67
126
|
return [...new Set(values.map((value) => value.trim()).filter((value) => value.length > 0))].sort((left, right) => left.localeCompare(right));
|
|
@@ -477,6 +536,7 @@ function resolveAction(target, options) {
|
|
|
477
536
|
options.manage ? "manage" : null,
|
|
478
537
|
options.reload ? "reload" : null,
|
|
479
538
|
options.doctor ? "doctor" : null,
|
|
539
|
+
options.catalog ? "catalog" : null,
|
|
480
540
|
options.init ? "init" : null,
|
|
481
541
|
options.scaffold ? "init" : null,
|
|
482
542
|
options.adopt ? "adopt" : null,
|
|
@@ -491,10 +551,13 @@ function resolveAction(target, options) {
|
|
|
491
551
|
if (typeof target === "string" && target.trim().toLowerCase() === "reload") {
|
|
492
552
|
return "reload";
|
|
493
553
|
}
|
|
554
|
+
if (typeof target === "string" && target.trim().toLowerCase() === "catalog") {
|
|
555
|
+
return "catalog";
|
|
556
|
+
}
|
|
494
557
|
if (typeof target === "string" && (target.trim().toLowerCase() === "init" || target.trim().toLowerCase() === "scaffold")) {
|
|
495
558
|
return "init";
|
|
496
559
|
}
|
|
497
|
-
throw new PmCliError("One action flag is required. Use one of: --install, --uninstall, --explore, --manage, --reload, --doctor, --init/--scaffold, --adopt, --adopt-all, --activate, --deactivate.", EXIT_CODE.USAGE);
|
|
560
|
+
throw new PmCliError("One action flag is required. Use one of: --install, --uninstall, --explore, --manage, --reload, --doctor, --catalog, --init/--scaffold, --adopt, --adopt-all, --activate, --deactivate.", EXIT_CODE.USAGE);
|
|
498
561
|
}
|
|
499
562
|
if (selected.length > 1) {
|
|
500
563
|
throw new PmCliError("Extension action flags are mutually exclusive.", EXIT_CODE.USAGE);
|
|
@@ -509,6 +572,77 @@ function resolveScope(options) {
|
|
|
509
572
|
}
|
|
510
573
|
return global ? "global" : "project";
|
|
511
574
|
}
|
|
575
|
+
async function buildBundledPackageCatalog(scope, global) {
|
|
576
|
+
const roots = resolveExtensionRoots(resolvePmRoot(process.cwd(), global.path), process.cwd());
|
|
577
|
+
const selectedRoot = scope === "global" ? roots.global : roots.project;
|
|
578
|
+
const managedStateRead = await readManagedExtensionState(selectedRoot);
|
|
579
|
+
const installedLocations = new Set(managedStateRead.state.entries
|
|
580
|
+
.filter((entry) => entry.scope === scope)
|
|
581
|
+
.map((entry) => path.resolve(entry.source.location)));
|
|
582
|
+
const packages = [];
|
|
583
|
+
for (const alias of await listBundledPackageAliases()) {
|
|
584
|
+
const packageRoot = await resolveBundledPackageRoot(alias);
|
|
585
|
+
const installScopeFlag = scope === "global" ? "--global" : "--project";
|
|
586
|
+
if (!packageRoot) {
|
|
587
|
+
packages.push({
|
|
588
|
+
alias,
|
|
589
|
+
bundled: true,
|
|
590
|
+
available: false,
|
|
591
|
+
installed: false,
|
|
592
|
+
install_target: alias,
|
|
593
|
+
install_command: `pm install ${alias} ${installScopeFlag}`,
|
|
594
|
+
});
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
const manifest = await readPmPackageManifest(packageRoot);
|
|
598
|
+
const repository = manifest.catalog?.links?.repository ?? manifest.package_repository_url;
|
|
599
|
+
const report = manifest.catalog?.links?.report ?? manifest.package_bugs_url;
|
|
600
|
+
const docs = manifest.catalog?.links?.docs ?? manifest.package_homepage;
|
|
601
|
+
const npm = manifest.catalog?.links?.npm ??
|
|
602
|
+
(manifest.package_name ? `https://www.npmjs.com/package/${encodeURIComponent(manifest.package_name)}` : undefined);
|
|
603
|
+
const metadataOnlyResources = Object.fromEntries(PM_PACKAGE_RESOURCE_KINDS
|
|
604
|
+
.filter((resourceKind) => resourceKind !== "extensions")
|
|
605
|
+
.map((resourceKind) => [resourceKind, manifest.resources[resourceKind] ?? []])
|
|
606
|
+
.filter(([, entries]) => Array.isArray(entries) && entries.length > 0));
|
|
607
|
+
packages.push({
|
|
608
|
+
alias,
|
|
609
|
+
bundled: true,
|
|
610
|
+
available: true,
|
|
611
|
+
installed: installedLocations.has(path.resolve(packageRoot)),
|
|
612
|
+
install_target: alias,
|
|
613
|
+
install_command: `pm install ${alias} ${installScopeFlag}`,
|
|
614
|
+
package_root: packageRoot,
|
|
615
|
+
package_name: manifest.package_name,
|
|
616
|
+
package_version: manifest.package_version,
|
|
617
|
+
description: manifest.catalog?.summary ?? manifest.package_description,
|
|
618
|
+
keywords: manifest.package_keywords ?? [],
|
|
619
|
+
resources: manifest.resources,
|
|
620
|
+
installable_resources: {
|
|
621
|
+
extensions: manifest.resources.extensions ?? [],
|
|
622
|
+
},
|
|
623
|
+
metadata_only_resources: metadataOnlyResources,
|
|
624
|
+
catalog: {
|
|
625
|
+
display_name: manifest.catalog?.display_name,
|
|
626
|
+
category: manifest.catalog?.category,
|
|
627
|
+
tags: manifest.catalog?.tags ?? manifest.package_keywords ?? [],
|
|
628
|
+
links: {
|
|
629
|
+
docs,
|
|
630
|
+
npm,
|
|
631
|
+
repository,
|
|
632
|
+
report,
|
|
633
|
+
},
|
|
634
|
+
media: manifest.catalog?.media,
|
|
635
|
+
},
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
return {
|
|
639
|
+
total: packages.length,
|
|
640
|
+
scope,
|
|
641
|
+
installable_resource_kinds: ["extensions"],
|
|
642
|
+
metadata_only_resource_kinds: PM_PACKAGE_RESOURCE_KINDS.filter((resourceKind) => resourceKind !== "extensions"),
|
|
643
|
+
packages,
|
|
644
|
+
};
|
|
645
|
+
}
|
|
512
646
|
function parseGithubPathSpec(pathSpec, input, refOverride) {
|
|
513
647
|
const segments = pathSpec
|
|
514
648
|
.split("/")
|
|
@@ -735,7 +869,7 @@ async function resolvePackageExtensionDirectory(packageRoot, sourceLabel) {
|
|
|
735
869
|
.sort((left, right) => left.localeCompare(right));
|
|
736
870
|
throw new PmCliError(`Package source "${sourceLabel}" contains multiple extension manifests. Provide an explicit extension path. Candidates: ${choices.join(", ")}`, EXIT_CODE.USAGE);
|
|
737
871
|
}
|
|
738
|
-
throw new PmCliError(`Unable to locate a pm extension manifest in package source "${sourceLabel}".
|
|
872
|
+
throw new PmCliError(`Unable to locate a pm extension manifest in package source "${sourceLabel}". Package installs currently activate only extension resources, so add package.json pm.extensions or an extensions/ directory. Metadata-only resources like pm.docs/pm.examples are catalog metadata and do not activate commands.`, EXIT_CODE.USAGE);
|
|
739
873
|
}
|
|
740
874
|
async function resolveGithubSourceDirectory(cloneDirectory, source) {
|
|
741
875
|
const candidatePaths = [];
|
|
@@ -966,20 +1100,66 @@ function applyDoctorRuntimeActivationState(extensions, loadResult, activationRes
|
|
|
966
1100
|
const loadedNames = new Set(loadResult.loaded.map((entry) => normalizeExtensionNameForMatch(entry.name)));
|
|
967
1101
|
const loadFailedNames = new Set(loadResult.failed.map((entry) => normalizeExtensionNameForMatch(entry.name)));
|
|
968
1102
|
const activationFailedNames = new Set(activationResult.failed.map((entry) => normalizeExtensionNameForMatch(entry.name)));
|
|
1103
|
+
const commandPathsByExtension = new Map();
|
|
1104
|
+
const actionPathsByExtension = new Map();
|
|
1105
|
+
const addCommandPath = (extensionName, commandPath) => {
|
|
1106
|
+
const normalizedName = normalizeExtensionNameForMatch(extensionName);
|
|
1107
|
+
const normalizedCommandPath = commandPath.trim();
|
|
1108
|
+
if (normalizedName.length === 0 || normalizedCommandPath.length === 0) {
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
const existing = commandPathsByExtension.get(normalizedName) ?? new Set();
|
|
1112
|
+
existing.add(normalizedCommandPath);
|
|
1113
|
+
commandPathsByExtension.set(normalizedName, existing);
|
|
1114
|
+
};
|
|
1115
|
+
const addActionPath = (extensionName, actionPath) => {
|
|
1116
|
+
const normalizedName = normalizeExtensionNameForMatch(extensionName);
|
|
1117
|
+
const normalizedActionPath = actionPath.trim();
|
|
1118
|
+
if (normalizedName.length === 0 || normalizedActionPath.length === 0) {
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
const existing = actionPathsByExtension.get(normalizedName) ?? new Set();
|
|
1122
|
+
existing.add(normalizedActionPath);
|
|
1123
|
+
actionPathsByExtension.set(normalizedName, existing);
|
|
1124
|
+
};
|
|
1125
|
+
for (const registration of activationResult.registrations.commands) {
|
|
1126
|
+
addCommandPath(registration.name, registration.command);
|
|
1127
|
+
addActionPath(registration.name, registration.action);
|
|
1128
|
+
}
|
|
1129
|
+
for (const handler of activationResult.commands.handlers) {
|
|
1130
|
+
addCommandPath(handler.name, handler.command);
|
|
1131
|
+
}
|
|
1132
|
+
for (const override of activationResult.commands.overrides) {
|
|
1133
|
+
addCommandPath(override.name, override.command);
|
|
1134
|
+
}
|
|
1135
|
+
const sortedPaths = (values) => {
|
|
1136
|
+
if (!values || values.size === 0) {
|
|
1137
|
+
return undefined;
|
|
1138
|
+
}
|
|
1139
|
+
return [...values].sort((left, right) => left.localeCompare(right));
|
|
1140
|
+
};
|
|
969
1141
|
return extensions.map((entry) => {
|
|
1142
|
+
const normalizedName = normalizeExtensionNameForMatch(entry.name);
|
|
1143
|
+
const commandPaths = sortedPaths(commandPathsByExtension.get(normalizedName));
|
|
1144
|
+
const actionPaths = sortedPaths(actionPathsByExtension.get(normalizedName));
|
|
1145
|
+
const runtimeMetadata = {
|
|
1146
|
+
...(commandPaths ? { command_paths: commandPaths } : {}),
|
|
1147
|
+
...(actionPaths ? { action_paths: actionPaths } : {}),
|
|
1148
|
+
};
|
|
970
1149
|
if (!entry.enabled) {
|
|
971
1150
|
return {
|
|
972
1151
|
...entry,
|
|
973
1152
|
runtime_active: false,
|
|
974
1153
|
activation_status: "not_loaded",
|
|
1154
|
+
...runtimeMetadata,
|
|
975
1155
|
};
|
|
976
1156
|
}
|
|
977
|
-
const normalizedName = normalizeExtensionNameForMatch(entry.name);
|
|
978
1157
|
if (loadFailedNames.has(normalizedName) || activationFailedNames.has(normalizedName)) {
|
|
979
1158
|
return {
|
|
980
1159
|
...entry,
|
|
981
1160
|
runtime_active: false,
|
|
982
1161
|
activation_status: "failed",
|
|
1162
|
+
...runtimeMetadata,
|
|
983
1163
|
};
|
|
984
1164
|
}
|
|
985
1165
|
if (loadedNames.has(normalizedName)) {
|
|
@@ -987,12 +1167,14 @@ function applyDoctorRuntimeActivationState(extensions, loadResult, activationRes
|
|
|
987
1167
|
...entry,
|
|
988
1168
|
runtime_active: true,
|
|
989
1169
|
activation_status: "ok",
|
|
1170
|
+
...runtimeMetadata,
|
|
990
1171
|
};
|
|
991
1172
|
}
|
|
992
1173
|
return {
|
|
993
1174
|
...entry,
|
|
994
1175
|
runtime_active: false,
|
|
995
1176
|
activation_status: "not_loaded",
|
|
1177
|
+
...runtimeMetadata,
|
|
996
1178
|
};
|
|
997
1179
|
});
|
|
998
1180
|
}
|
|
@@ -1127,13 +1309,16 @@ function requireTarget(target, action) {
|
|
|
1127
1309
|
const normalized = target?.trim();
|
|
1128
1310
|
if (!normalized) {
|
|
1129
1311
|
if (action === "init") {
|
|
1130
|
-
throw new PmCliError('Action "init" requires a scaffold target path (for example: pm
|
|
1312
|
+
throw new PmCliError('Action "init" requires a scaffold target path (for example: pm package init ./my-package or pm extension init ./my-extension).', EXIT_CODE.USAGE);
|
|
1131
1313
|
}
|
|
1132
1314
|
throw new PmCliError(`Action "${action}" requires an extension name or source target argument.`, EXIT_CODE.USAGE);
|
|
1133
1315
|
}
|
|
1134
1316
|
return normalized;
|
|
1135
1317
|
}
|
|
1136
|
-
function
|
|
1318
|
+
function lifecycleFlagCommand(options, action) {
|
|
1319
|
+
return options.vocabulary === "package" ? `pm package ${action}` : `pm extension --${action}`;
|
|
1320
|
+
}
|
|
1321
|
+
function buildStarterExtensionScaffoldFiles(extensionName, commandName, vocabulary) {
|
|
1137
1322
|
const manifest = `${JSON.stringify({
|
|
1138
1323
|
name: extensionName,
|
|
1139
1324
|
version: "0.1.0",
|
|
@@ -1162,7 +1347,7 @@ function buildStarterExtensionScaffoldFiles(extensionName, commandName) {
|
|
|
1162
1347
|
const readme = [
|
|
1163
1348
|
`# ${extensionName}`,
|
|
1164
1349
|
"",
|
|
1165
|
-
|
|
1350
|
+
`Generated by \`${vocabulary === "package" ? "pm package init" : "pm extension init"}\`.`,
|
|
1166
1351
|
"",
|
|
1167
1352
|
"## Included Files",
|
|
1168
1353
|
"- `manifest.json`: extension metadata and capabilities.",
|
|
@@ -1170,9 +1355,9 @@ function buildStarterExtensionScaffoldFiles(extensionName, commandName) {
|
|
|
1170
1355
|
"",
|
|
1171
1356
|
"## Quick Start",
|
|
1172
1357
|
"```bash",
|
|
1173
|
-
"pm extension --install --project <scaffold-path
|
|
1358
|
+
`${vocabulary === "package" ? "pm install" : "pm extension --install"} --project <scaffold-path>`,
|
|
1174
1359
|
`pm ${commandName}`,
|
|
1175
|
-
"pm extension --doctor --project --detail summary
|
|
1360
|
+
`${vocabulary === "package" ? "pm package doctor" : "pm extension --doctor"} --project --detail summary`,
|
|
1176
1361
|
"```",
|
|
1177
1362
|
"",
|
|
1178
1363
|
"## Notes",
|
|
@@ -1186,12 +1371,12 @@ function buildStarterExtensionScaffoldFiles(extensionName, commandName) {
|
|
|
1186
1371
|
"README.md": readme,
|
|
1187
1372
|
};
|
|
1188
1373
|
}
|
|
1189
|
-
async function scaffoldExtensionProject(target) {
|
|
1374
|
+
async function scaffoldExtensionProject(target, vocabulary = "extension") {
|
|
1190
1375
|
const normalizedTarget = target.trim();
|
|
1191
1376
|
const targetPath = path.resolve(process.cwd(), normalizedTarget);
|
|
1192
1377
|
const extensionName = normalizeManagedDirectoryName(path.basename(targetPath));
|
|
1193
1378
|
const commandName = `${extensionName} ping`;
|
|
1194
|
-
const scaffoldFiles = buildStarterExtensionScaffoldFiles(extensionName, commandName);
|
|
1379
|
+
const scaffoldFiles = buildStarterExtensionScaffoldFiles(extensionName, commandName, vocabulary);
|
|
1195
1380
|
let createdDirectory = false;
|
|
1196
1381
|
if (await pathExists(targetPath)) {
|
|
1197
1382
|
const existingTargetStats = await fs.stat(targetPath);
|
|
@@ -1248,7 +1433,7 @@ function classifyDoctorLoadFailureWarnings(loadFailures) {
|
|
|
1248
1433
|
}
|
|
1249
1434
|
return [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
|
|
1250
1435
|
}
|
|
1251
|
-
function buildExtensionTriageSummary(scope, warnings, extensions) {
|
|
1436
|
+
function buildExtensionTriageSummary(scope, warnings, extensions, options = {}) {
|
|
1252
1437
|
const normalizedWarnings = [...new Set(warnings)].sort((left, right) => left.localeCompare(right));
|
|
1253
1438
|
const managedTotal = extensions.filter((entry) => entry.managed).length;
|
|
1254
1439
|
const enabledTotal = extensions.filter((entry) => entry.enabled).length;
|
|
@@ -1288,7 +1473,7 @@ function buildExtensionTriageSummary(scope, warnings, extensions) {
|
|
|
1288
1473
|
const remediation = [];
|
|
1289
1474
|
if (normalizedWarnings.length > 0) {
|
|
1290
1475
|
if (normalizedWarnings.some((warning) => warning.startsWith("extension_manifest_"))) {
|
|
1291
|
-
remediation.push(`Run
|
|
1476
|
+
remediation.push(`Run ${lifecycleFlagCommand(options, "explore")} ${scopeFlag} to inspect discovered manifests and directories.`);
|
|
1292
1477
|
}
|
|
1293
1478
|
if (normalizedWarnings.some((warning) => warning.startsWith("extension_capability_unknown:"))) {
|
|
1294
1479
|
remediation.push(`Unknown extension capabilities detected. Allowed capabilities: ${KNOWN_EXTENSION_CAPABILITIES.join(", ")}. ` +
|
|
@@ -1304,14 +1489,14 @@ function buildExtensionTriageSummary(scope, warnings, extensions) {
|
|
|
1304
1489
|
}
|
|
1305
1490
|
if (normalizedWarnings.some((warning) => warning.startsWith("extension_load_failed_sdk_dependency_missing:"))) {
|
|
1306
1491
|
remediation.push(`Detected extension load failures caused by missing SDK dependency resolution. ` +
|
|
1307
|
-
`Ensure extension package dependencies include "@unbrained/pm-cli" and reinstall dependencies before running
|
|
1492
|
+
`Ensure extension package dependencies include "@unbrained/pm-cli" and reinstall dependencies before running ${lifecycleFlagCommand(options, "doctor")} ${scopeFlag}.`);
|
|
1308
1493
|
}
|
|
1309
1494
|
if (normalizedWarnings.some((warning) => warning.startsWith("extension_load_failed_module_mode_mismatch:"))) {
|
|
1310
1495
|
remediation.push(`Detected extension module-mode mismatches. For ESM-based extension entries/imports, set package.json "type": "module" ` +
|
|
1311
|
-
`or use an explicit .mjs entry and rerun
|
|
1496
|
+
`or use an explicit .mjs entry and rerun ${lifecycleFlagCommand(options, "doctor")} ${scopeFlag}.`);
|
|
1312
1497
|
}
|
|
1313
1498
|
if (updateCheckFailedTotal > 0) {
|
|
1314
|
-
remediation.push(`Run
|
|
1499
|
+
remediation.push(`Run ${lifecycleFlagCommand(options, "manage")} ${scopeFlag} after validating network and repository access.`);
|
|
1315
1500
|
}
|
|
1316
1501
|
if (normalizedWarnings.some((warning) => warning.startsWith("extension_manager_state_"))) {
|
|
1317
1502
|
remediation.push(`Review and repair ${scope} managed extension state file if schema/read warnings persist.`);
|
|
@@ -1321,19 +1506,19 @@ function buildExtensionTriageSummary(scope, warnings, extensions) {
|
|
|
1321
1506
|
}
|
|
1322
1507
|
}
|
|
1323
1508
|
if (updateHealthPartial) {
|
|
1324
|
-
remediation.push(`Update-check coverage is partial because unmanaged extensions need adoption. Adopt existing installs via
|
|
1509
|
+
remediation.push(`Update-check coverage is partial because unmanaged extensions need adoption. Adopt existing installs via ${lifecycleFlagCommand(options, "manage")} ${scopeFlag} --fix-managed-state (or ${lifecycleFlagCommand(options, "adopt-all")} ${scopeFlag}, ${lifecycleFlagCommand(options, "adopt")} <name> ${scopeFlag}, or reinstall via ${lifecycleFlagCommand(options, "install")} ${scopeFlag} <source>).`);
|
|
1325
1510
|
}
|
|
1326
1511
|
else if (skippedUnmanagedTotal > 0) {
|
|
1327
|
-
remediation.push(`Loaded unmanaged extensions are currently treated as informational. Use
|
|
1512
|
+
remediation.push(`Loaded unmanaged extensions are currently treated as informational. Use ${lifecycleFlagCommand(options, "manage")} ${scopeFlag} --fix-managed-state to adopt them for update checks.`);
|
|
1328
1513
|
}
|
|
1329
1514
|
if (skippedNonGithubTotal > 0) {
|
|
1330
1515
|
remediation.push(`Non-GitHub managed extensions are skipped by update checks. Use doctor output for non-update diagnostics.`);
|
|
1331
1516
|
}
|
|
1332
1517
|
if (updateAvailableTotal > 0) {
|
|
1333
|
-
remediation.push(`Update available managed extensions via
|
|
1518
|
+
remediation.push(`Update available managed extensions via ${lifecycleFlagCommand(options, "install")} ${scopeFlag} <source>.`);
|
|
1334
1519
|
}
|
|
1335
1520
|
if (remediation.length === 0) {
|
|
1336
|
-
remediation.push(`No immediate action required. Re-run
|
|
1521
|
+
remediation.push(`No immediate action required. Re-run ${lifecycleFlagCommand(options, "manage")} ${scopeFlag} after extension changes.`);
|
|
1337
1522
|
}
|
|
1338
1523
|
return {
|
|
1339
1524
|
status: effectiveWarnings.length === 0 ? "ok" : "warn",
|
|
@@ -1485,6 +1670,9 @@ export async function runExtension(target, options, global) {
|
|
|
1485
1670
|
if (action === "reload" && normalizedInput === "reload") {
|
|
1486
1671
|
return undefined;
|
|
1487
1672
|
}
|
|
1673
|
+
if (action === "catalog" && normalizedInput === "catalog") {
|
|
1674
|
+
return undefined;
|
|
1675
|
+
}
|
|
1488
1676
|
const inferredInitAlias = action === "init" &&
|
|
1489
1677
|
options.init !== true &&
|
|
1490
1678
|
options.scaffold !== true &&
|
|
@@ -1516,7 +1704,7 @@ export async function runExtension(target, options, global) {
|
|
|
1516
1704
|
throw new PmCliError('Action "init" does not accept --gh/--github/--ref options.', EXIT_CODE.USAGE);
|
|
1517
1705
|
}
|
|
1518
1706
|
const scaffoldTarget = requireTarget(normalizedTarget, action);
|
|
1519
|
-
const scaffold = await scaffoldExtensionProject(scaffoldTarget);
|
|
1707
|
+
const scaffold = await scaffoldExtensionProject(scaffoldTarget, options.vocabulary ?? "extension");
|
|
1520
1708
|
const quotedTargetPath = JSON.stringify(scaffold.target_path);
|
|
1521
1709
|
return withResult({
|
|
1522
1710
|
scaffolded: scaffold.created_directory || scaffold.files.some((entry) => entry.status === "created"),
|
|
@@ -1528,9 +1716,9 @@ export async function runExtension(target, options, global) {
|
|
|
1528
1716
|
created_directory: scaffold.created_directory,
|
|
1529
1717
|
files: scaffold.files,
|
|
1530
1718
|
next_steps: [
|
|
1531
|
-
`Install the scaffold: pm extension --install --project ${quotedTargetPath}`,
|
|
1719
|
+
`Install the scaffold: ${options.vocabulary === "package" ? "pm install --project" : "pm extension --install --project"} ${quotedTargetPath}`,
|
|
1532
1720
|
`Smoke-test command path: pm ${scaffold.command_name}`,
|
|
1533
|
-
|
|
1721
|
+
`Run diagnostics: ${options.vocabulary === "package" ? "pm package doctor" : "pm extension --doctor"} --project --detail summary`,
|
|
1534
1722
|
],
|
|
1535
1723
|
});
|
|
1536
1724
|
}
|
|
@@ -1582,6 +1770,12 @@ export async function runExtension(target, options, global) {
|
|
|
1582
1770
|
}
|
|
1583
1771
|
return withResult(details);
|
|
1584
1772
|
}
|
|
1773
|
+
if (action === "catalog") {
|
|
1774
|
+
if (typeof normalizedTarget === "string" && normalizedTarget.length > 0 && normalizedTarget !== "catalog") {
|
|
1775
|
+
throw new PmCliError('Action "catalog" does not accept a package target.', EXIT_CODE.USAGE);
|
|
1776
|
+
}
|
|
1777
|
+
return withResult(await buildBundledPackageCatalog(scope, global));
|
|
1778
|
+
}
|
|
1585
1779
|
if (action === "install") {
|
|
1586
1780
|
const githubOption = resolveGithubOption(options);
|
|
1587
1781
|
const explicitSourceInput = githubOption ?? requireTarget(normalizedTarget, action);
|
|
@@ -1589,7 +1783,7 @@ export async function runExtension(target, options, global) {
|
|
|
1589
1783
|
if (typeof options.ref === "string" && options.ref.trim().length > 0) {
|
|
1590
1784
|
throw new PmCliError('Action "install all" does not accept --ref.', EXIT_CODE.USAGE);
|
|
1591
1785
|
}
|
|
1592
|
-
const aliases = listBundledPackageAliases();
|
|
1786
|
+
const aliases = await listBundledPackageAliases();
|
|
1593
1787
|
const packages = [];
|
|
1594
1788
|
for (const alias of aliases) {
|
|
1595
1789
|
packages.push({
|
|
@@ -1719,7 +1913,7 @@ export async function runExtension(target, options, global) {
|
|
|
1719
1913
|
const adoption = await adoptUnmanagedExtensions(resolvedRoots.selected_root, scope, installed.extensions, managedStateRead.state);
|
|
1720
1914
|
const refreshedInstalled = await listInstalledExtensions(resolvedRoots.selected_root, scope, settings, adoption.state);
|
|
1721
1915
|
warnings.push(...refreshedInstalled.warnings);
|
|
1722
|
-
const triage = buildExtensionTriageSummary(scope, warnings, refreshedInstalled.extensions);
|
|
1916
|
+
const triage = buildExtensionTriageSummary(scope, warnings, refreshedInstalled.extensions, options);
|
|
1723
1917
|
warnings.push(...triage.warnings);
|
|
1724
1918
|
const adoptedDetails = adoption.adopted_entries.map((entry) => {
|
|
1725
1919
|
const refreshedEntry = refreshedInstalled.extensions.find((candidate) => normalizeExtensionNameForMatch(candidate.name) === normalizeExtensionNameForMatch(entry.name) &&
|
|
@@ -1926,7 +2120,7 @@ export async function runExtension(target, options, global) {
|
|
|
1926
2120
|
.filter((entry) => entry.update_check_status === "failed")
|
|
1927
2121
|
.map((entry) => `extension_update_check_failed:${entry.name}`);
|
|
1928
2122
|
warnings.push(...updateCheckWarnings);
|
|
1929
|
-
const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions);
|
|
2123
|
+
const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions, options);
|
|
1930
2124
|
warnings.push(...triage.warnings);
|
|
1931
2125
|
const normalizedWarnings = [...triage.warnings];
|
|
1932
2126
|
const policySummary = {
|
|
@@ -1956,10 +2150,18 @@ export async function runExtension(target, options, global) {
|
|
|
1956
2150
|
...new Set([
|
|
1957
2151
|
...triage.remediation,
|
|
1958
2152
|
...(loadResult.failed.length > 0
|
|
1959
|
-
? [
|
|
2153
|
+
? [
|
|
2154
|
+
options.vocabulary === "package"
|
|
2155
|
+
? "Run pm package explore --project and pm package explore --global to inspect load failures."
|
|
2156
|
+
: "Run pm extension --explore --project and pm extension --explore --global to inspect load failures.",
|
|
2157
|
+
]
|
|
1960
2158
|
: []),
|
|
1961
2159
|
...(activationResult.failed.length > 0
|
|
1962
|
-
? [
|
|
2160
|
+
? [
|
|
2161
|
+
options.vocabulary === "package"
|
|
2162
|
+
? "Review activation failures in pm package doctor --detail deep output."
|
|
2163
|
+
: "Review activation failures in pm extension --doctor --detail deep output.",
|
|
2164
|
+
]
|
|
1963
2165
|
: []),
|
|
1964
2166
|
...(managedStateFix && managedStateFix.adopted_entries.length > 0
|
|
1965
2167
|
? [`Managed-state fix adopted ${managedStateFix.adopted_entries.length} extension(s).`]
|
|
@@ -2136,7 +2338,7 @@ export async function runExtension(target, options, global) {
|
|
|
2136
2338
|
}
|
|
2137
2339
|
let runtimeProbeSummary;
|
|
2138
2340
|
let runtimeInstalledExtensions = refreshedInstalled.extensions;
|
|
2139
|
-
if (action === "
|
|
2341
|
+
if (action === "explore" || options.runtimeProbe === true) {
|
|
2140
2342
|
const loadResult = await loadExtensions({
|
|
2141
2343
|
pmRoot: resolvedRoots.pm_root,
|
|
2142
2344
|
settings,
|
|
@@ -2153,6 +2355,7 @@ export async function runExtension(target, options, global) {
|
|
|
2153
2355
|
runtimeProbeSummary = {
|
|
2154
2356
|
requested: true,
|
|
2155
2357
|
executed: true,
|
|
2358
|
+
reason: action === "explore" ? "explore_defaults_to_runtime_probe" : "runtime_probe_requested",
|
|
2156
2359
|
load_failure_count: loadResult.failed.length,
|
|
2157
2360
|
activation_failure_count: activationResult.failed.length,
|
|
2158
2361
|
warning_count: [...new Set([...loadResult.warnings, ...activationResult.warnings])].length,
|
|
@@ -2161,11 +2364,11 @@ export async function runExtension(target, options, global) {
|
|
|
2161
2364
|
}
|
|
2162
2365
|
else if (action === "manage") {
|
|
2163
2366
|
runtimeProbeSummary = {
|
|
2164
|
-
requested:
|
|
2367
|
+
requested: false,
|
|
2165
2368
|
executed: false,
|
|
2166
2369
|
};
|
|
2167
2370
|
}
|
|
2168
|
-
const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions);
|
|
2371
|
+
const triage = buildExtensionTriageSummary(scope, warnings, runtimeInstalledExtensions, options);
|
|
2169
2372
|
warnings.push(...triage.warnings);
|
|
2170
2373
|
const details = {
|
|
2171
2374
|
total: runtimeInstalledExtensions.length,
|
|
@@ -2176,6 +2379,9 @@ export async function runExtension(target, options, global) {
|
|
|
2176
2379
|
triage,
|
|
2177
2380
|
policy: configuredPolicy,
|
|
2178
2381
|
};
|
|
2382
|
+
if (action === "explore") {
|
|
2383
|
+
details.runtime_probe = runtimeProbeSummary;
|
|
2384
|
+
}
|
|
2179
2385
|
if (action === "manage") {
|
|
2180
2386
|
details.runtime_probe = runtimeProbeSummary;
|
|
2181
2387
|
details.managed_state_fix =
|