@uniqbit/mate-core 0.17.1 → 0.17.2-canary.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniqbit/mate-core",
3
- "version": "0.17.1",
3
+ "version": "0.17.2-canary.0",
4
4
  "description": "Core framework and plugin APIs for Mate.",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -11,7 +11,7 @@ export async function runPluginCommand(
11
11
  await runPluginInstallCommand(argv);
12
12
  return;
13
13
  case "verify":
14
- await runPluginVerifyCommand();
14
+ await runPluginVerifyCommand(argv);
15
15
  return;
16
16
  default:
17
17
  console.error(`Unknown plugin command: ${subcommand ?? ""}`);
@@ -1,19 +1,22 @@
1
1
  import { FRAMEWORK_NAME } from "../../../framework";
2
2
  import { resolveInstallContext } from "../../../lib/install";
3
- import { verifyDeclaredPlugins } from "../../../tools/setup/dynamic-plugins/verify";
3
+ import { inspectDeclaredPlugins } from "../../../tools/setup/dynamic-plugins/verify";
4
4
 
5
5
  /**
6
6
  * @command mate plugin verify
7
- * @description Strict, installation-free check that every plugin declared by the companion is allowed by `MATE_ALLOWED_PLUGINS`, installed, and loadable with the current environment. Exits non-zero naming each failing package.
7
+ * @description Strict, installation-free check that every plugin declared by the companion is allowed by `MATE_ALLOWED_PLUGINS`, installed, and loadable with the current environment. Exits non-zero naming each failing package. With `--json`, prints `{"capabilities": [...]}` listing the capability IDs the verified plugins provide.
8
8
  */
9
- export async function runPluginVerifyCommand(cwd = process.cwd()): Promise<boolean> {
9
+ export async function runPluginVerifyCommand(
10
+ argv: string[] = [],
11
+ cwd = process.cwd(),
12
+ ): Promise<boolean> {
10
13
  const context = await resolveInstallContext(cwd);
11
14
  if ((context.kind !== "companion" && context.kind !== "hub") || !context.companionPath) {
12
15
  process.stderr.write(`${FRAMEWORK_NAME}: \`plugin verify\` requires a companion context.\n`);
13
16
  process.exitCode = 1;
14
17
  return false;
15
18
  }
16
- const failures = await verifyDeclaredPlugins(context.companionPath);
19
+ const { failures, capabilities } = await inspectDeclaredPlugins(context.companionPath);
17
20
  for (const failure of failures) {
18
21
  process.stderr.write(`${FRAMEWORK_NAME}: plugin ${failure.package}: ${failure.reason}\n`);
19
22
  }
@@ -21,5 +24,6 @@ export async function runPluginVerifyCommand(cwd = process.cwd()): Promise<boole
21
24
  process.exitCode = 1;
22
25
  return false;
23
26
  }
27
+ if (argv.includes("--json")) process.stdout.write(`${JSON.stringify({ capabilities })}\n`);
24
28
  return true;
25
29
  }
@@ -17,6 +17,12 @@ export interface PluginVerificationFailure {
17
17
  reason: string;
18
18
  }
19
19
 
20
+ export interface PluginInspection {
21
+ failures: PluginVerificationFailure[];
22
+ /** IDs of the capabilities the loaded, allowlisted plugins provide. */
23
+ capabilities: string[];
24
+ }
25
+
20
26
  /**
21
27
  * Strict, installation-free check of every declared plugin: allowed, installed
22
28
  * and loadable with the effective environment. Unlike hydration it fails
@@ -27,14 +33,22 @@ export async function verifyDeclaredPlugins(
27
33
  companionPath: string,
28
34
  deps: DynamicPluginLoadDeps = {},
29
35
  ): Promise<PluginVerificationFailure[]> {
36
+ return (await inspectDeclaredPlugins(companionPath, deps)).failures;
37
+ }
38
+
39
+ export async function inspectDeclaredPlugins(
40
+ companionPath: string,
41
+ deps: DynamicPluginLoadDeps = {},
42
+ ): Promise<PluginInspection> {
30
43
  const env = deps.env ?? process.env;
31
44
  const failures: PluginVerificationFailure[] = [];
45
+ const capabilities: string[] = [];
32
46
  let policy: ReturnType<typeof readPluginPolicy>;
33
47
  try {
34
48
  policy = readPluginPolicy(env);
35
49
  } catch (error) {
36
50
  if (!(error instanceof PluginPolicyError)) throw error;
37
- return [{ package: "(allowlist)", reason: error.message }];
51
+ return { failures: [{ package: "(allowlist)", reason: error.message }], capabilities };
38
52
  }
39
53
 
40
54
  const declarations: PluginDeclaration[] = [];
@@ -65,6 +79,7 @@ export async function verifyDeclaredPlugins(
65
79
  // oxlint-disable-next-line no-await-in-loop -- declared order is part of the contract
66
80
  const result = await loadDynamicPlugin(companionPath, declaration, { ...deps, env });
67
81
  if (!result.ok) failures.push({ package: name, reason: result.warning });
82
+ else if (result.plugin.kind === "capability") capabilities.push(result.plugin.id);
68
83
  }
69
- return failures;
84
+ return { failures, capabilities };
70
85
  }