@uniqbit/mate-core 0.18.3-canary.0 → 0.18.3-canary.1
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,7 +1,10 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
|
|
3
3
|
import { FRAMEWORK_NAME } from "../../framework";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getDefaultSetupSelections,
|
|
6
|
+
listSetupCapabilityCompatibilities,
|
|
7
|
+
} from "./setup-compatibilities";
|
|
5
8
|
import { YamlFileStore } from "./yaml-file-store";
|
|
6
9
|
import { ConfigError, type FrameworkConfig } from "./types";
|
|
7
10
|
|
|
@@ -143,7 +146,7 @@ function validatePluginDeclarations(config: FrameworkConfig): void {
|
|
|
143
146
|
|
|
144
147
|
export const AUDIENCE_NAME_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
|
|
145
148
|
|
|
146
|
-
const AUDIENCE_KEYS = ["plugins", "studio"] as const;
|
|
149
|
+
const AUDIENCE_KEYS = ["capabilities", "plugins", "studio"] as const;
|
|
147
150
|
|
|
148
151
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
149
152
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -182,6 +185,43 @@ function validateAudiencePlugins(audience: string, plugins: unknown): Map<string
|
|
|
182
185
|
return versions;
|
|
183
186
|
}
|
|
184
187
|
|
|
188
|
+
function validateAudienceCapabilities(
|
|
189
|
+
audience: string,
|
|
190
|
+
capabilities: unknown,
|
|
191
|
+
baseNames: ReadonlySet<string>,
|
|
192
|
+
): void {
|
|
193
|
+
if (!Array.isArray(capabilities)) {
|
|
194
|
+
throw new ConfigError(`audience "${audience}": capabilities must be a list.`);
|
|
195
|
+
}
|
|
196
|
+
const builtin = new Set(
|
|
197
|
+
listSetupCapabilityCompatibilities().map((entry) => entry.capability.name),
|
|
198
|
+
);
|
|
199
|
+
const seen = new Set<string>();
|
|
200
|
+
for (const entry of capabilities) {
|
|
201
|
+
if (!isRecord(entry) || typeof entry.name !== "string" || entry.name === "") {
|
|
202
|
+
throw new ConfigError(
|
|
203
|
+
`audience "${audience}": capabilities entry must have a string name: ${JSON.stringify(entry)}`,
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
if (builtin.has(entry.name)) {
|
|
207
|
+
throw new ConfigError(
|
|
208
|
+
`audience "${audience}": capability "${entry.name}" is built in; declare it in the base capabilities.`,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
if (baseNames.has(entry.name)) {
|
|
212
|
+
throw new ConfigError(
|
|
213
|
+
`audience "${audience}": capability "${entry.name}" is also declared in base capabilities.`,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
if (seen.has(entry.name)) {
|
|
217
|
+
throw new ConfigError(
|
|
218
|
+
`audience "${audience}": capability "${entry.name}" is declared more than once.`,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
seen.add(entry.name);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
185
225
|
/**
|
|
186
226
|
* Validates the optional `audiences` mapping. Only companions may declare
|
|
187
227
|
* audiences; names are safe identifiers and keys form a closed set so typos
|
|
@@ -198,6 +238,7 @@ function validateAudiences(config: FrameworkConfig): void {
|
|
|
198
238
|
}
|
|
199
239
|
|
|
200
240
|
const basePackages = new Set((config.plugins ?? []).map((plugin) => plugin.package));
|
|
241
|
+
const baseCapabilities = new Set((config.capabilities ?? []).map((entry) => entry.name));
|
|
201
242
|
const seen = new Map<string, { audience: string; version: string }>();
|
|
202
243
|
|
|
203
244
|
for (const [name, audience] of Object.entries(audiences)) {
|
|
@@ -217,6 +258,10 @@ function validateAudiences(config: FrameworkConfig): void {
|
|
|
217
258
|
}
|
|
218
259
|
}
|
|
219
260
|
|
|
261
|
+
if (audience.capabilities !== undefined) {
|
|
262
|
+
validateAudienceCapabilities(name, audience.capabilities, baseCapabilities);
|
|
263
|
+
}
|
|
264
|
+
|
|
220
265
|
if (audience.plugins !== undefined) {
|
|
221
266
|
for (const [pkg, version] of validateAudiencePlugins(name, audience.plugins)) {
|
|
222
267
|
if (basePackages.has(pkg)) {
|
|
@@ -127,9 +127,12 @@ export interface StudioTerminalConfig {
|
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
129
|
* A named slice of a companion's configuration, activated by `MATE_AUDIENCE`.
|
|
130
|
-
* Plugins add to the base
|
|
130
|
+
* Plugins and capabilities add to the base lists; `studio.terminal.agent`
|
|
131
|
+
* overrides the base. Capabilities here name what a declared plugin provides,
|
|
132
|
+
* never a built-in one, so what `install` writes does not depend on the audience.
|
|
131
133
|
*/
|
|
132
134
|
export interface AudienceConfig {
|
|
135
|
+
capabilities?: CapabilityConfig[];
|
|
133
136
|
plugins?: PluginDeclaration[];
|
|
134
137
|
studio?: { terminal?: StudioTerminalConfig };
|
|
135
138
|
}
|